Merge "Enables private and storage networks"
[apex.git] / ci / deploy.sh
1 #!/bin/bash
2
3 # Deploy script to install provisioning server for OPNFV Apex
4 # author: Dan Radez (dradez@redhat.com)
5 # author: Tim Rozet (trozet@redhat.com)
6 #
7 # Based on RDO Manager http://www.rdoproject.org
8
9 set -e
10
11 ##VARIABLES
12 if [ "$TERM" != "unknown" ]; then
13   reset=$(tput sgr0)
14   blue=$(tput setaf 4)
15   red=$(tput setaf 1)
16   green=$(tput setaf 2)
17 else
18   reset=""
19   blue=""
20   red=""
21   green=""
22 fi
23
24 vm_index=4
25 ha_enabled="TRUE"
26 ping_site="8.8.8.8"
27 ntp_server="pool.ntp.org"
28 net_isolation_enabled="TRUE"
29 post_config="TRUE"
30
31 declare -i CNT
32 declare UNDERCLOUD
33 declare -A deploy_options_array
34 declare -A NET_MAP
35
36 SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
37 DEPLOY_OPTIONS=""
38 RESOURCES=/var/opt/opnfv/stack
39 CONFIG=/var/opt/opnfv
40 INSTACKENV=$CONFIG/instackenv.json
41 OPNFV_NETWORK_TYPES="admin_network private_network public_network storage_network"
42 # Netmap used to map networks to OVS bridge names
43 NET_MAP['admin_network']="brbm"
44 NET_MAP['private_network']="brbm1"
45 NET_MAP['public_network']="brbm2"
46 NET_MAP['storage_network']="brbm3"
47
48 ##LIBRARIES
49 source $CONFIG/lib/common-functions.sh
50
51 ##FUNCTIONS
52 ##translates yaml into variables
53 ##params: filename, prefix (ex. "config_")
54 ##usage: parse_yaml opnfv_ksgen_settings.yml "config_"
55 parse_yaml() {
56    local prefix=$2
57    local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
58    sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
59         -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p"  $1 |
60    awk -F$fs '{
61       indent = length($1)/2;
62       vname[indent] = $2;
63       for (i in vname) {if (i > indent) {delete vname[i]}}
64       if (length($3) > 0) {
65          vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
66          printf("%s%s%s=%s\n", "'$prefix'",vn, $2, $3);
67       }
68    }'
69 }
70
71 ##checks if prefix exists in string
72 ##params: string, prefix
73 ##usage: contains_prefix "deploy_setting_launcher=1" "deploy_setting"
74 contains_prefix() {
75   local mystr=$1
76   local prefix=$2
77   if echo $mystr | grep -E "^$prefix.*$" > /dev/null; then
78     return 0
79   else
80     return 1
81   fi
82 }
83 ##parses variable from a string with '='
84 ##and removes global prefix
85 ##params: string, prefix
86 ##usage: parse_setting_var 'deploy_myvar=2' 'deploy_'
87 parse_setting_var() {
88   local mystr=$1
89   local prefix=$2
90   if echo $mystr | grep -E "^.+\=" > /dev/null; then
91     echo $(echo $mystr | grep -Eo "^.+\=" | tr -d '=' |  sed 's/^'"$prefix"'//')
92   else
93     return 1
94   fi
95 }
96 ##parses value from a string with '='
97 ##params: string
98 ##usage: parse_setting_value
99 parse_setting_value() {
100   local mystr=$1
101   echo $(echo $mystr | grep -Eo "\=.*$" | tr -d '=')
102 }
103 ##parses network settings yaml into globals
104 parse_network_settings() {
105   local required_network_settings="cidr"
106   local common_optional_network_settings="usable_ip_range"
107   local admin_network_optional_settings="provisioner_ip dhcp_range introspection_range"
108   local public_network_optional_settings="floating_ip_range gateway provisioner_ip"
109   local nic_value cidr
110
111   eval $(parse_yaml ${NETSETS})
112   for network in ${OPNFV_NETWORK_TYPES}; do
113     if [[ $(eval echo \${${network}_enabled}) == 'true' ]]; then
114       enabled_network_list+="${network} "
115     elif [ "${network}" == 'admin_network' ]; then
116       echo -e "${red}ERROR: You must enable admin_network and configure it explicitly or use auto-detection${reset}"
117       exit 1
118     elif [ "${network}" == 'public_network' ]; then
119       echo -e "${red}ERROR: You must enable public_network and configure it explicitly or use auto-detection${reset}"
120       exit 1
121     else
122       echo -e "${blue}INFO: Network: ${network} is disabled, will collapse into admin_network"
123     fi
124   done
125
126   # check for enabled network values
127   for enabled_network in ${enabled_network_list}; do
128     # detect required settings first to continue
129     echo -e "${blue}INFO: Detecting Required settings for: ${enabled_network}${reset}"
130     for setting in ${required_network_settings}; do
131       eval "setting_value=\${${enabled_network}_${setting}}"
132       if [ -z "${setting_value}" ]; then
133         # if setting is missing we try to autodetect
134         eval "nic_value=\${${enabled_network}_bridged_interface}"
135         if [ -n "$nic_value" ]; then
136           setting_value=$(eval find_${setting} ${nic_value})
137           if [ -n "$setting_value" ]; then
138             eval "${enabled_network}_${setting}=${setting_value}"
139             echo -e "${blue}INFO: Auto-detection: ${enabled_network}_${setting}: ${setting_value}${reset}"
140           else
141             echo -e "${red}ERROR: Auto-detection failed: ${setting} not found using interface: ${nic_value}${reset}"
142             exit 1
143           fi
144         else
145           echo -e "${red}ERROR: Required setting: ${setting} not found, and bridge interface not provided\
146 for Auto-detection${reset}"
147           exit 1
148         fi
149       else
150         echo -e "${blue}INFO: ${enabled_network}_${setting}: ${setting_value}${reset}"
151       fi
152     done
153     echo -e "${blue}INFO: Detecting Common settings for: ${enabled_network}${reset}"
154     # detect optional common settings
155     # these settings can be auto-generated if missing
156     for setting in ${common_optional_network_settings}; do
157       eval "setting_value=\${${enabled_network}_${setting}}"
158       if [ -z "${setting_value}" ]; then
159         if [ -n "$nic_value" ]; then
160           setting_value=$(eval find_${setting} ${nic_value})
161         else
162           setting_value=''
163           echo -e "${blue}INFO: Skipping Auto-detection, NIC not specified for ${enabled_network}.  Attempting Auto-generation...${reset}"
164         fi
165         if [ -n "$setting_value" ]; then
166           eval "${enabled_network}_${setting}=${setting_value}"
167           echo -e "${blue}INFO: Auto-detection: ${enabled_network}_${setting}: ${setting_value}${reset}"
168         else
169           # if Auto-detection fails we can auto-generate with CIDR
170           eval "cidr=\${${enabled_network}_cidr}"
171           if [ -n "$cidr" ]; then
172             echo -e "${blue}INFO: Auto-generating: ${setting}${reset}"
173             setting_value=$(eval generate_${setting} ${cidr})
174           else
175             setting_value=''
176             echo -e "${red}ERROR: Auto-generation failed: required parameter CIDR missing for network ${enabled_network}${reset}"
177           fi
178           if [ -n "$setting_value" ]; then
179             eval "${enabled_network}_${setting}=${setting_value}"
180             echo -e "${blue}INFO: Auto-generated: ${enabled_network}_${setting}: ${setting_value}${reset}"
181           else
182             echo -e "${red}ERROR: Auto-generation failed: ${setting} not found${reset}"
183             exit 1
184           fi
185         fi
186       else
187         echo -e "${blue}INFO: ${enabled_network}_${setting}: ${setting_value}${reset}"
188       fi
189     done
190     echo -e "${blue}INFO: Detecting Network Specific settings for: ${enabled_network}${reset}"
191     # detect network specific settings
192     if [ -n $(eval echo \${${network}_optional_settings}) ]; then
193       eval "network_specific_settings=\${${enabled_network}_optional_settings}"
194       for setting in ${network_specific_settings}; do
195         eval "setting_value=\${${enabled_network}_${setting}}"
196         if [ -z "${setting_value}" ]; then
197           if [ -n "$nic_value" ]; then
198             setting_value=$(eval find_${setting} ${nic_value})
199           else
200             setting_value=''
201             echo -e "${blue}INFO: Skipping Auto-detection, NIC not specified for ${enabled_network}.  Attempting Auto-generation...${reset}"
202           fi
203           if [ -n "$setting_value" ]; then
204             eval "${enabled_network}_${setting}=${setting_value}"
205             echo -e "${blue}INFO: Auto-detection: ${enabled_network}_${setting}: ${setting_value}${reset}"
206           else
207             eval "cidr=\${${enabled_network}_cidr}"
208             if [ -n "$cidr" ]; then
209               setting_value=$(eval generate_${setting} ${cidr})
210             else
211               setting_value=''
212               echo -e "${red}ERROR: Auto-generation failed: required parameter CIDR missing for network ${enabled_network}${reset}"
213             fi
214             if [ -n "$setting_value" ]; then
215               eval "${enabled_network}_${setting}=${setting_value}"
216               echo -e "${blue}INFO: Auto-generated: ${enabled_network}_${setting}: ${setting_value}${reset}"
217             else
218               echo -e "${red}ERROR: Auto-generation failed: ${setting} not found${reset}"
219               exit 1
220             fi
221           fi
222         else
223           echo -e "${blue}INFO: ${enabled_network}_${setting}: ${setting_value}${reset}"
224         fi
225       done
226     fi
227   done
228 }
229 ##parses deploy settings yaml into globals and options array
230 ##params: none
231 ##usage:  parse_deploy_settings
232 parse_deploy_settings() {
233   local global_prefix="deploy_global_params_"
234   local options_prefix="deploy_deploy_options_"
235   local myvar myvalue
236   local settings=$(parse_yaml $DEPLOY_SETTINGS_FILE "deploy_")
237
238   for this_setting in $settings; do
239     if contains_prefix $this_setting $global_prefix; then
240       myvar=$(parse_setting_var $this_setting $global_prefix)
241       if [ -z "$myvar" ]; then
242         echo -e "${red}ERROR: while parsing ${DEPLOY_SETTINGS_FILE} for setting: ${this_setting}${reset}"
243       fi
244       myvalue=$(parse_setting_value $this_setting)
245       # Do not override variables set by cmdline
246       if [ -z "$(eval echo \$$myvar)" ]; then
247         eval "$myvar=\$myvalue"
248         echo -e "${blue}Global parameter set: ${myvar}:${myvalue}${reset}"
249       else
250         echo -e "${blue}Global parameter already set: ${myvar}${reset}"
251       fi
252     elif contains_prefix $this_setting $options_prefix; then
253       myvar=$(parse_setting_var $this_setting $options_prefix)
254       if [ -z "$myvar" ]; then
255         echo -e "${red}ERROR: while parsing ${DEPLOY_SETTINGS_FILE} for setting: ${this_setting}${reset}"
256       fi
257       myvalue=$(parse_setting_value $this_setting)
258       deploy_options_array[$myvar]=$myvalue
259       echo -e "${blue}Deploy option set: ${myvar}:${myvalue}${reset}"
260     fi
261   done
262 }
263 ##parses baremetal yaml settings into compatible json
264 ##writes the json to $CONFIG/instackenv_tmp.json
265 ##params: none
266 ##usage: parse_inventory_file
267 parse_inventory_file() {
268   local inventory=$(parse_yaml $INVENTORY_FILE)
269   local node_list
270   local node_prefix="node"
271   local node_count=0
272   local node_total
273   local inventory_list
274
275   # detect number of nodes
276   for entry in $inventory; do
277     if echo $entry | grep -Eo "^nodes_node[0-9]+_" > /dev/null; then
278       this_node=$(echo $entry | grep -Eo "^nodes_node[0-9]+_")
279       if [[ $inventory_list != *"$this_node"* ]]; then
280         inventory_list+="$this_node "
281       fi
282     fi
283   done
284
285   inventory_list=$(echo $inventory_list | sed 's/ $//')
286
287   for node in $inventory_list; do
288     ((node_count+=1))
289   done
290
291   node_total=$node_count
292
293   if [[ "$node_total" -lt 5 && ha_enabled == "TRUE" ]]; then
294     echo -e "${red}ERROR: You must provide at least 5 nodes for HA baremetal deployment${reset}"
295     exit 1
296   elif [[ "$node_total" -lt 2 ]]; then
297     echo -e "${red}ERROR: You must provide at least 2 nodes for non-HA baremetal deployment${reset}"
298     exit 1
299   fi
300
301   eval $(parse_yaml $INVENTORY_FILE)
302
303   instack_env_output="
304 {
305  \"nodes\" : [
306
307 "
308   node_count=0
309   for node in $inventory_list; do
310     ((node_count+=1))
311     node_output="
312         {
313           \"pm_password\": \"$(eval echo \${${node}ipmi_pass})\",
314           \"pm_type\": \"pxe_ipmitool\",
315           \"mac\": [
316             \"$(eval echo \${${node}mac_address})\"
317           ],
318           \"cpu\": \"$(eval echo \${${node}cpus})\",
319           \"memory\": \"$(eval echo \${${node}memory})\",
320           \"disk\": \"$(eval echo \${${node}disk})\",
321           \"arch\": \"$(eval echo \${${node}arch})\",
322           \"pm_user\": \"$(eval echo \${${node}ipmi_user})\",
323           \"pm_addr\": \"$(eval echo \${${node}ipmi_ip})\",
324           \"capabilities\": \"$(eval echo \${${node}capabilities})\"
325 "
326     instack_env_output+=${node_output}
327     if [ $node_count -lt $node_total ]; then
328       instack_env_output+="        },"
329     else
330       instack_env_output+="        }"
331     fi
332   done
333
334   instack_env_output+='
335   ]
336 }
337 '
338   #Copy instackenv.json to undercloud for baremetal
339   echo -e "{blue}Parsed instackenv JSON:\n${instack_env_output}${reset}"
340   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
341 cat > instackenv.json << EOF
342 $instack_env_output
343 EOF
344 EOI
345
346 }
347 ##verify internet connectivity
348 #params: none
349 function verify_internet {
350   if ping -c 2 $ping_site > /dev/null; then
351     if ping -c 2 www.google.com > /dev/null; then
352       echo "${blue}Internet connectivity detected${reset}"
353       return 0
354     else
355       echo "${red}Internet connectivity detected, but DNS lookup failed${reset}"
356       return 1
357     fi
358   else
359     echo "${red}No internet connectivity detected${reset}"
360     return 1
361   fi
362 }
363
364 ##download dependencies if missing and configure host
365 #params: none
366 function configure_deps {
367   if ! verify_internet; then
368     echo "${red}Will not download dependencies${reset}"
369     internet=false
370   fi
371
372   # verify ip forwarding
373   if sysctl net.ipv4.ip_forward | grep 0; then
374     sudo sysctl -w net.ipv4.ip_forward=1
375     sudo sh -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf"
376   fi
377
378   # ensure no dhcp server is running on jumphost
379   if ! sudo systemctl status dhcpd | grep dead; then
380     echo "${red}WARN: DHCP Server detected on jumphost, disabling...${reset}"
381     sudo systemctl stop dhcpd
382     sudo systemctl disable dhcpd
383   fi
384
385   # ensure networks are configured
386   systemctl start openvswitch
387
388   # If flat we only use admin network
389   if [[ "$net_isolation_enabled" == "FALSE" ]]; then
390     virsh_enabled_networks="admin_network"
391   # For baremetal we only need to create/attach instack to admin and public
392   elif [ "$virtual" == "FALSE" ]; then
393     virsh_enabled_networks="admin_network public_network"
394   else
395     virsh_enabled_networks=$enabled_network_list
396   fi
397
398   for network in ${OPNFV_NETWORK_TYPES}; do
399     ovs-vsctl list-br | grep ${NET_MAP[$network]} > /dev/null || ovs-vsctl add-br ${NET_MAP[$network]}
400     virsh net-list --all | grep ${NET_MAP[$network]} > /dev/null || virsh net-create $CONFIG/${NET_MAP[$network]}-net.xml
401     virsh net-list | grep -E "${NET_MAP[$network]}\s+active" > /dev/null || virsh net-start ${NET_MAP[$network]}
402   done
403
404   echo -e "${blue}INFO: Bridges set: ${reset}"
405   ovs-vsctl list-br
406   echo -e "${blue}INFO: virsh networks set: ${reset}"
407   virsh net-list
408
409   if [[ -z "$virtual" || "$virtual" == "FALSE" ]]; then
410     # bridge interfaces to correct OVS instances for baremetal deployment
411     for network in ${enabled_network_list}; do
412       this_interface=$(eval echo \${${network}_bridged_interface})
413       # check if this a bridged interface for this network
414       if [[ ! -z "$this_interface" || "$this_interface" != "none" ]]; then
415         if ! attach_interface_to_ovs ${NET_MAP[$network]} ${this_interface} ${network}; then
416           echo -e "${red}ERROR: Unable to bridge interface ${this_interface} to bridge ${NET_MAP[$network]} for enabled network: ${network}${reset}"
417           exit 1
418         else
419           echo -e "${blue}INFO: Interface ${this_interface} bridged to bridge ${NET_MAP[$network]} for enabled network: ${network}${reset}"
420         fi
421       else
422         echo "${red}ERROR: Unable to determine interface to bridge to for enabled network: ${network}${reset}"
423         exit 1
424       fi
425     done
426   fi
427
428   # ensure storage pool exists and is started
429   virsh pool-list --all | grep default > /dev/null || virsh pool-create $CONFIG/default-pool.xml
430   virsh pool-list | grep -Eo "default\s+active" > /dev/null || virsh pool-start default
431
432   if virsh net-list | grep default > /dev/null; then
433     num_ints_same_subnet=$(ip addr show | grep "inet 192.168.122" | wc -l)
434     if [ "$num_ints_same_subnet" -gt 1 ]; then
435       virsh net-destroy default
436       ##go edit /etc/libvirt/qemu/networks/default.xml
437       sed -i 's/192.168.122/192.168.123/g' /etc/libvirt/qemu/networks/default.xml
438       sed -i 's/192.168.122/192.168.123/g' instackenv-virt.json
439       sleep 5
440       virsh net-start default
441       virsh net-autostart default
442     fi
443   fi
444
445   if ! egrep '^flags.*(vmx|svm)' /proc/cpuinfo > /dev/null; then
446     echo "${red}virtualization extensions not found, kvm kernel module insertion may fail.\n  \
447 Are you sure you have enabled vmx in your bios or hypervisor?${reset}"
448   fi
449
450   if ! lsmod | grep kvm > /dev/null; then modprobe kvm; fi
451   if ! lsmod | grep kvm_intel > /dev/null; then modprobe kvm_intel; fi
452
453   if ! lsmod | grep kvm > /dev/null; then
454     echo "${red}kvm kernel modules not loaded!${reset}"
455     return 1
456   fi
457
458   ##sshkeygen for root
459   if [ ! -e ~/.ssh/id_rsa.pub ]; then
460     ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
461   fi
462
463   echo "${blue}All dependencies installed and running${reset}"
464 }
465
466 ##verify vm exists, an has a dhcp lease assigned to it
467 ##params: none
468 function setup_instack_vm {
469   if ! virsh list --all | grep instack > /dev/null; then
470       #virsh vol-create default instack.qcow2.xml
471       virsh define $CONFIG/instack.xml
472
473       #Upload instack image
474       #virsh vol-create default --file instack.qcow2.xml
475       virsh vol-create-as default instack.qcow2 30G --format qcow2
476
477       ### this doesn't work for some reason I was getting hangup events so using cp instead
478       #virsh vol-upload --pool default --vol instack.qcow2 --file $CONFIG/stack/instack.qcow2
479       #2015-12-05 12:57:20.569+0000: 8755: info : libvirt version: 1.2.8, package: 16.el7_1.5 (CentOS BuildSystem <http://bugs.centos.org>, 2015-11-03-13:56:46, worker1.bsys.centos.org)
480       #2015-12-05 12:57:20.569+0000: 8755: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
481       #2015-12-05 12:57:20.569+0000: 8756: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
482       #error: cannot close volume instack.qcow2
483       #error: internal error: received hangup / error event on socket
484       #error: Reconnected to the hypervisor
485
486       instack_dst=/var/lib/libvirt/images/instack.qcow2
487       cp -f $RESOURCES/instack.qcow2 $instack_dst
488
489       # resize instack machine
490       echo "Checking if instack needs to be resized..."
491       instack_size=$(LIBGUESTFS_BACKEND=direct virt-filesystems --long -h --all -a $instack_dst |grep device | grep -Eo "[0-9\.]+G" | sed -n 's/\([0-9][0-9]*\).*/\1/p')
492       if [ "$instack_size" -lt 30 ]; then
493         qemu-img resize /var/lib/libvirt/images/instack.qcow2 +25G
494         LIBGUESTFS_BACKEND=direct virt-resize --expand /dev/sda1 $RESOURCES/instack.qcow2 $instack_dst
495         LIBGUESTFS_BACKEND=direct virt-customize -a $instack_dst --run-command 'xfs_growfs -d /dev/sda1 || true'
496         new_size=$(LIBGUESTFS_BACKEND=direct virt-filesystems --long -h --all -a $instack_dst |grep filesystem | grep -Eo "[0-9\.]+G" | sed -n 's/\([0-9][0-9]*\).*/\1/p')
497         if [ "$new_size" -lt 30 ]; then
498           echo "Error resizing instack machine, disk size is ${new_size}"
499           exit 1
500         else
501           echo "instack successfully resized"
502         fi
503       else
504         echo "skipped instack resize, upstream is large enough"
505       fi
506
507   else
508       echo "Found Instack VM, using existing VM"
509   fi
510
511   # if the VM is not running update the authkeys and start it
512   if ! virsh list | grep instack > /dev/null; then
513     echo "Injecting ssh key to instack VM"
514     virt-customize -c qemu:///system -d instack --run-command "mkdir /root/.ssh/" \
515         --upload ~/.ssh/id_rsa.pub:/root/.ssh/authorized_keys \
516         --run-command "chmod 600 /root/.ssh/authorized_keys && restorecon /root/.ssh/authorized_keys" \
517         --run-command "cp /root/.ssh/authorized_keys /home/stack/.ssh/" \
518         --run-command "chown stack:stack /home/stack/.ssh/authorized_keys && chmod 600 /home/stack/.ssh/authorized_keys"
519     virsh start instack
520   fi
521
522   sleep 3 # let DHCP happen
523
524   CNT=10
525   echo -n "${blue}Waiting for instack's dhcp address${reset}"
526   while ! grep instack /var/lib/libvirt/dnsmasq/default.leases > /dev/null && [ $CNT -gt 0 ]; do
527       echo -n "."
528       sleep 3
529       CNT=CNT-1
530   done
531
532   # get the instack VM IP
533   UNDERCLOUD=$(grep instack /var/lib/libvirt/dnsmasq/default.leases | awk '{print $3}' | head -n 1)
534   if [ -z "$UNDERCLOUD" ]; then
535     #if not found then dnsmasq may be using leasefile-ro
536     instack_mac=$(virsh domiflist instack | grep default | \
537                   grep -Eo "[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+")
538     UNDERCLOUD=$(/usr/sbin/arp -e | grep ${instack_mac} | awk {'print $1'})
539
540     if [ -z "$UNDERCLOUD" ]; then
541       echo "\n\nNever got IP for Instack. Can Not Continue."
542       exit 1
543     else
544       echo -e "${blue}\rInstack VM has IP $UNDERCLOUD${reset}"
545     fi
546   else
547      echo -e "${blue}\rInstack VM has IP $UNDERCLOUD${reset}"
548   fi
549
550   CNT=10
551   echo -en "${blue}\rValidating instack VM connectivity${reset}"
552   while ! ping -c 1 $UNDERCLOUD > /dev/null && [ $CNT -gt 0 ]; do
553       echo -n "."
554       sleep 3
555       CNT=$CNT-1
556   done
557   if [ "$CNT" -eq 0 ]; then
558       echo "Failed to contact Instack. Can Not Continue"
559       exit 1
560   fi
561   CNT=10
562   while ! ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "echo ''" 2>&1> /dev/null && [ $CNT -gt 0 ]; do
563       echo -n "."
564       sleep 3
565       CNT=$CNT-1
566   done
567   if [ "$CNT" -eq 0 ]; then
568       echo "Failed to connect to Instack. Can Not Continue"
569       exit 1
570   fi
571
572   # extra space to overwrite the previous connectivity output
573   echo -e "${blue}\r                                                                 ${reset}"
574
575   #add the instack public interface if net isolation is enabled (more than just admin network)
576   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
577     virsh attach-interface --domain instack --type network --source ${NET_MAP['public_network']} --model rtl8139 --config --live
578     sleep 1
579     ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "if ! ip a s eth2 | grep ${public_network_provisioner_ip} > /dev/null; then ip a a ${public_network_provisioner_ip}/${public_network_cidr##*/} dev eth2; ip link set up dev eth2; fi"
580   fi
581   # ssh key fix for stack user
582   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "restorecon -r /home/stack"
583 }
584
585 ##Create virtual nodes in virsh
586 ##params: none
587 function setup_virtual_baremetal {
588   for i in $(seq 0 $vm_index); do
589     if ! virsh list --all | grep baremetalbrbm_brbm1_brbm2_brbm3_${i} > /dev/null; then
590       if [ ! -e $CONFIG/baremetalbrbm_brbm1_brbm2_brbm3_${i}.xml ]; then
591         define_virtual_node baremetalbrbm_brbm1_brbm2_brbm3_${i}
592       fi
593       # Fix for ramdisk using wrong pxeboot interface
594       # TODO: revisit this and see if there's a more proper fix
595       sed -i "/^\s*<source network='brbm2'\/>/{
596         N
597         s/^\(.*\)virtio\(.*\)$/\1rtl8139\2/
598         }" $CONFIG/baremetalbrbm_brbm1_brbm2_brbm3_${i}.xml
599       virsh define $CONFIG/baremetalbrbm_brbm1_brbm2_brbm3_${i}.xml
600     else
601       echo "Found Baremetal ${i} VM, using existing VM"
602     fi
603     virsh vol-list default | grep baremetalbrbm_brbm1_brbm2_brbm3_${i} 2>&1> /dev/null || virsh vol-create-as default baremetalbrbm_brbm1_brbm2_brbm3_${i}.qcow2 40G --format qcow2
604   done
605
606 }
607
608 ##Set network-environment settings
609 ##params: network-environment file to edit
610 function configure_network_environment {
611   local tht_dir nic_ext
612   tht_dir=/usr/share/openstack-tripleo-heat-templates/network
613   nic_ext=''
614
615   sed -i '/ControlPlaneSubnetCidr/c\\  ControlPlaneSubnetCidr: "'${admin_network_cidr##*/}'"' $1
616   sed -i '/ControlPlaneDefaultRoute/c\\  ControlPlaneDefaultRoute: '${admin_network_provisioner_ip}'' $1
617   sed -i '/ExternalNetCidr/c\\  ExternalNetCidr: '${public_network_cidr}'' $1
618   sed -i "/ExternalAllocationPools/c\\  ExternalAllocationPools: [{'start': '${public_network_usable_ip_range%%,*}', 'end': '${public_network_usable_ip_range##*,}'}]" $1
619   sed -i '/ExternalInterfaceDefaultRoute/c\\  ExternalInterfaceDefaultRoute: '${public_network_gateway}'' $1
620   sed -i '/EC2MetadataIp/c\\  EC2MetadataIp: '${admin_network_provisioner_ip}'' $1
621
622   # check for private network
623   if [[ ! -z "$private_network_enabled" && "$private_network_enabled" == "true" ]]; then
624       sed -i 's#^.*Network::Tenant.*$#  OS::TripleO::Network::Tenant: '${tht_dir}'/tenant.yaml#' $1
625       sed -i 's#^.*Controller::Ports::TenantPort:.*$#  OS::TripleO::Controller::Ports::TenantPort: '${tht_dir}'/ports/tenant.yaml#' $1
626       sed -i 's#^.*Compute::Ports::TenantPort:.*$#  OS::TripleO::Compute::Ports::TenantPort: '${tht_dir}'/ports/tenant.yaml#' $1
627       sed -i "/TenantAllocationPools/c\\  TenantAllocationPools: [{'start': '${private_network_usable_ip_range%%,*}', 'end': '${private_network_usable_ip_range##*,}'}]" $1
628       sed -i '/TenantNetCidr/c\\  TenantNetCidr: '${private_network_cidr}'' $1
629       nic_ext+=_private
630   else
631       sed -i 's#^.*Network::Tenant.*$#  OS::TripleO::Network::Tenant: '${tht_dir}'/noop.yaml#' $1
632       sed -i 's#^.*Controller::Ports::TenantPort:.*$#  OS::TripleO::Controller::Ports::TenantPort: '${tht_dir}'/ports/noop.yaml#' $1
633       sed -i 's#^.*Compute::Ports::TenantPort:.*$#  OS::TripleO::Compute::Ports::TenantPort: '${tht_dir}'/ports/noop.yaml#' $1
634   fi
635
636   # check for storage network
637   if [[ ! -z "$storage_network_enabled" && "$storage_network_enabled" == "true" ]]; then
638       sed -i 's#^.*Network::Storage.*$#  OS::TripleO::Network::Storage: '${tht_dir}'/storage.yaml#' $1
639       sed -i 's#^.*Controller::Ports::StoragePort:.*$#  OS::TripleO::Controller::Ports::StoragePort: '${tht_dir}'/ports/storage.yaml#' $1
640       sed -i 's#^.*Compute::Ports::StoragePort:.*$#  OS::TripleO::Compute::Ports::StoragePort: '${tht_dir}'/ports/storage.yaml#' $1
641       sed -i "/StorageAllocationPools/c\\  StorageAllocationPools: [{'start': '${storage_network_usable_ip_range%%,*}', 'end': '${storage_network_usable_ip_range##*,}'}]" $1
642       sed -i '/StorageNetCidr/c\\  StorageNetCidr: '${storage_network_cidr}'' $1
643       nic_ext+=_storage
644   else
645       sed -i 's#^.*Network::Storage.*$#  OS::TripleO::Network::Storage: '${tht_dir}'/noop.yaml#' $1
646       sed -i 's#^.*Controller::Ports::StoragePort:.*$#  OS::TripleO::Controller::Ports::StoragePort: '${tht_dir}'/ports/noop.yaml#' $1
647       sed -i 's#^.*Compute::Ports::StoragePort:.*$#  OS::TripleO::Compute::Ports::StoragePort: '${tht_dir}'/ports/noop.yaml#' $1
648   fi
649
650   # set nics appropriately
651   sed -i 's#^.*Compute::Net::SoftwareConfig:.*$#  OS::TripleO::Compute::Net::SoftwareConfig: nics/compute'${nic_ext}'.yaml#' $1
652   sed -i 's#^.*Controller::Net::SoftwareConfig:.*$#  OS::TripleO::Controller::Net::SoftwareConfig: nics/controller'${nic_ext}'.yaml#' $1
653 }
654 ##Copy over the glance images and instack json file
655 ##params: none
656 function configure_undercloud {
657
658   echo
659   echo "Copying configuration file and disk images to instack"
660   scp ${SSH_OPTIONS[@]} $RESOURCES/overcloud-full.qcow2 "stack@$UNDERCLOUD":
661   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
662     configure_network_environment $CONFIG/network-environment.yaml
663     echo -e "${blue}Network Environment set for Deployment: ${reset}"
664     cat $CONFIG/network-environment.yaml
665     scp ${SSH_OPTIONS[@]} $CONFIG/network-environment.yaml "stack@$UNDERCLOUD":
666   fi
667   scp ${SSH_OPTIONS[@]} -r $CONFIG/nics/ "stack@$UNDERCLOUD":
668
669   # ensure stack user on instack machine has an ssh key
670   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "if [ ! -e ~/.ssh/id_rsa.pub ]; then ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa; fi"
671
672   if [ "$virtual" == "TRUE" ]; then
673
674       # copy the instack vm's stack user's pub key to
675       # root's auth keys so that instack can control
676       # vm power on the hypervisor
677       ssh ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> /root/.ssh/authorized_keys
678
679       # fix MACs to match new setup
680       for i in $(seq 0 $vm_index); do
681         pyscript="import json
682 data = json.load(open('$CONFIG/instackenv-virt.json'))
683 print data['nodes'][$i]['mac'][0]"
684
685         old_mac=$(python -c "$pyscript")
686         new_mac=$(virsh dumpxml baremetalbrbm_brbm1_brbm2_brbm3_$i | grep "mac address" | cut -d = -f2 | grep -Eo "[0-9a-f:]+")
687         # this doesn't work with multiple vnics on the vms
688         #if [ "$old_mac" != "$new_mac" ]; then
689         #  echo "${blue}Modifying MAC for node from $old_mac to ${new_mac}${reset}"
690         #  sed -i 's/'"$old_mac"'/'"$new_mac"'/' $CONFIG/instackenv-virt.json
691         #fi
692       done
693
694       DEPLOY_OPTIONS+=" --libvirt-type qemu"
695       INSTACKENV=$CONFIG/instackenv-virt.json
696
697       # upload instackenv file to Instack for virtual deployment
698       scp ${SSH_OPTIONS[@]} $INSTACKENV "stack@$UNDERCLOUD":instackenv.json
699   fi
700
701   # allow stack to control power management on the hypervisor via sshkey
702   # only if this is a virtual deployment
703   if [ "$virtual" == "TRUE" ]; then
704       ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
705 while read -r line; do
706   stack_key=\${stack_key}\\\\\\\\n\${line}
707 done < <(cat ~/.ssh/id_rsa)
708 stack_key=\$(echo \$stack_key | sed 's/\\\\\\\\n//')
709 sed -i 's~INSERT_STACK_USER_PRIV_KEY~'"\$stack_key"'~' instackenv.json
710 EOI
711   fi
712
713   # copy stack's ssh key to this users authorized keys
714   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
715
716   # disable requiretty for sudo
717   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "sed -i 's/Defaults\s*requiretty//'" /etc/sudoers
718
719   # configure undercloud on Undercloud VM
720   echo "Running undercloud configuration."
721   echo "Logging undercloud configuration to instack:/home/stack/apex-undercloud-install.log"
722   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
723 if [[ "$net_isolation_enabled" == "TRUE" ]]; then
724   sed -i 's/#local_ip/local_ip/' undercloud.conf
725   sed -i 's/#network_gateway/network_gateway/' undercloud.conf
726   sed -i 's/#network_cidr/network_cidr/' undercloud.conf
727   sed -i 's/#dhcp_start/dhcp_start/' undercloud.conf
728   sed -i 's/#dhcp_end/dhcp_end/' undercloud.conf
729   sed -i 's/#inspection_iprange/inspection_iprange/' undercloud.conf
730   sed -i 's/#undercloud_debug/undercloud_debug/' undercloud.conf
731
732   openstack-config --set undercloud.conf DEFAULT local_ip ${admin_network_provisioner_ip}/${admin_network_cidr##*/}
733   openstack-config --set undercloud.conf DEFAULT network_gateway ${admin_network_provisioner_ip}
734   openstack-config --set undercloud.conf DEFAULT network_cidr ${admin_network_cidr}
735   openstack-config --set undercloud.conf DEFAULT dhcp_start ${admin_network_dhcp_range%%,*}
736   openstack-config --set undercloud.conf DEFAULT dhcp_end ${admin_network_dhcp_range##*,}
737   openstack-config --set undercloud.conf DEFAULT inspection_iprange ${admin_network_introspection_range}
738   openstack-config --set undercloud.conf DEFAULT undercloud_debug false
739
740 fi
741
742 sudo sed -i '/CephClusterFSID:/c\\  CephClusterFSID: \\x27$(cat /proc/sys/kernel/random/uuid)\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
743 sudo sed -i '/CephMonKey:/c\\  CephMonKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
744 sudo sed -i '/CephAdminKey:/c\\  CephAdminKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
745
746 openstack undercloud install &> apex-undercloud-install.log
747 sleep 30
748 sudo systemctl restart openstack-glance-api
749 sudo systemctl restart openstack-nova-conductor
750 sudo systemctl restart openstack-nova-compute
751 EOI
752 # WORKAROUND: must restart the above services to fix sync problem with nova compute manager
753 # TODO: revisit and file a bug if necessary. This should eventually be removed
754 # as well as glance api problem
755 echo -e "${blue}INFO: Sleeping 15 seconds while services come back from restart${reset}"
756 sleep 15
757
758 }
759
760 ##preping it for deployment and launch the deploy
761 ##params: none
762 function undercloud_prep_overcloud_deploy {
763
764   if [[ ${#deploy_options_array[@]} -eq 0 || ${deploy_options_array['sdn_controller']} == 'opendaylight' ]]; then
765     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/opendaylight.yaml"
766   elif [ ${deploy_options_array['sdn_controller']} == 'opendaylight-external' ]; then
767     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/opendaylight-external.yaml"
768   elif [ ${deploy_options_array['sdn_controller']} == 'onos' ]; then
769     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/onos.yaml"
770   elif [ ${deploy_options_array['sdn_controller']} == 'opencontrail' ]; then
771     echo -e "${red}ERROR: OpenContrail is currently unsupported...exiting${reset}"
772     exit 1
773   fi
774
775   # make sure ceph is installed
776   DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml"
777
778   # check if HA is enabled
779   if [[ "$ha_enabled" == "TRUE" ]]; then
780      DEPLOY_OPTIONS+=" --control-scale 3 --compute-scale 2"
781      DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/puppet-pacemaker.yaml"
782   fi
783
784   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
785      #DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/network-isolation.yaml"
786      DEPLOY_OPTIONS+=" -e network-environment.yaml"
787   fi
788
789   if [[ "$ha_enabled" == "TRUE" ]] || [[ "$net_isolation_enabled" == "TRUE" ]]; then
790      DEPLOY_OPTIONS+=" --ntp-server $ntp_server"
791   fi
792
793   if [[ ! "$virtual" == "TRUE" ]]; then
794      DEPLOY_OPTIONS+=" --control-flavor control --compute-flavor compute"
795   fi
796
797   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
798 source stackrc
799 set -o errexit
800 echo "Uploading overcloud glance images"
801 openstack overcloud image upload
802 echo "Configuring undercloud and discovering nodes"
803 openstack baremetal import --json instackenv.json
804 openstack baremetal configure boot
805 openstack baremetal introspection bulk start
806 echo "Configuring flavors"
807 for flavor in baremetal control compute; do
808   echo -e "${blue}INFO: Updating flavor: \${flavor}${reset}"
809   if openstack flavor list | grep \${flavor}; then
810     openstack flavor delete \${flavor}
811   fi
812   openstack flavor create --id auto --ram 4096 --disk 39 --vcpus 1 \${flavor}
813   if ! openstack flavor list | grep \${flavor}; then
814     echo -e "${red}ERROR: Unable to create flavor \${flavor}${reset}"
815   fi
816 done
817 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" baremetal
818 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" --property "capabilities:profile"="control" control
819 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" --property "capabilities:profile"="compute" compute
820 echo "Configuring nameserver on ctlplane network"
821 neutron subnet-update \$(neutron subnet-list | grep -v id | grep -v \\\\-\\\\- | awk {'print \$2'}) --dns-nameserver 8.8.8.8
822 echo "Executing overcloud deployment, this should run for an extended period without output."
823 sleep 60 #wait for Hypervisor stats to check-in to nova
824 # save deploy command so it can be used for debugging
825 cat > deploy_command << EOF
826 openstack overcloud deploy --templates $DEPLOY_OPTIONS
827 EOF
828 openstack overcloud deploy --templates $DEPLOY_OPTIONS
829 EOI
830
831 }
832
833 ##Post configuration after install
834 ##params: none
835 function configure_post_install {
836   local opnfv_attach_networks ovs_ip ip_range net_cidr tmp_ip
837   opnfv_attach_networks="admin_network public_network"
838
839   echo -e "${blue}INFO: Post Install Configuration Running...${reset}"
840
841   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
842 source overcloudrc
843 set -o errexit
844 echo "Configuring Neutron external network"
845 neutron net-create external --router:external=True
846 neutron subnet-create --name external-net --disable-dhcp external --gateway ${public_network_gateway} --allocation-pool start=${public_network_floating_ip_range%%,*},end=${public_network_floating_ip_range##*,} ${public_network_cidr}
847 EOI
848
849   echo -e "${blue}INFO: Checking if OVS bridges have IP addresses...${reset}"
850   for network in ${opnfv_attach_networks}; do
851     ovs_ip=$(find_ip ${NET_MAP[$network]})
852     tmp_ip=''
853     if [ -n "$ovs_ip" ]; then
854       echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} has IP address ${ovs_ip}${reset}"
855     else
856       echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} missing IP, will configure${reset}"
857       # use last IP of allocation pool
858       eval "ip_range=\${${network}_usable_ip_range}"
859       ovs_ip=${ip_range##*,}
860       eval "net_cidr=\${${network}_cidr}"
861       sudo ip addr add ${ovs_ip}/${net_cidr##*/} dev ${NET_MAP[$network]}
862       tmp_ip=$(find_ip ${NET_MAP[$network]})
863       if [ -n "$tmp_ip" ]; then
864         echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} IP set: ${tmp_ip}${reset}"
865         continue
866       else
867         echo -e "${red}ERROR: Unable to set OVS Bridge ${NET_MAP[$network]} with IP: ${ovs_ip}${reset}"
868         return 1
869       fi
870     fi
871   done
872 }
873
874 display_usage() {
875   echo -e "Usage:\n$0 [arguments] \n"
876   echo -e "   -c|--config : Directory to configuration files. Optional.  Defaults to /var/opt/opnfv/ \n"
877   echo -e "   -d|--deploy-settings : Full path to deploy settings yaml file. Optional.  Defaults to null \n"
878   echo -e "   -i|--inventory : Full path to inventory yaml file. Required only for baremetal \n"
879   echo -e "   -n|--net-settings : Full path to network settings file. Optional. \n"
880   echo -e "   -p|--ping-site : site to use to verify IP connectivity. Optional. Defaults to 8.8.8.8 \n"
881   echo -e "   -r|--resources : Directory to deployment resources. Optional.  Defaults to /var/opt/opnfv/stack \n"
882   echo -e "   -v|--virtual : Virtualize overcloud nodes instead of using baremetal. \n"
883   echo -e "   --no-ha : disable High Availability deployment scheme, this assumes a single controller and single compute node \n"
884   echo -e "   --flat : disable Network Isolation and use a single flat network for the underlay network.\n"
885   echo -e "   --no-post-config : disable Post Install configuration."
886 }
887
888 ##translates the command line parameters into variables
889 ##params: $@ the entire command line is passed
890 ##usage: parse_cmd_line() "$@"
891 parse_cmdline() {
892   echo -e "\n\n${blue}This script is used to deploy the Apex Installer and Provision OPNFV Target System${reset}\n\n"
893   echo "Use -h to display help"
894   sleep 2
895
896   while [ "${1:0:1}" = "-" ]
897   do
898     case "$1" in
899         -h|--help)
900                 display_usage
901                 exit 0
902             ;;
903         -c|--config)
904                 CONFIG=$2
905                 echo "Deployment Configuration Directory Overridden to: $2"
906                 shift 2
907             ;;
908         -d|--deploy-settings)
909                 DEPLOY_SETTINGS_FILE=$2
910                 echo "Deployment Configuration file: $2"
911                 shift 2
912             ;;
913         -i|--inventory)
914                 INVENTORY_FILE=$2
915                 shift 2
916             ;;
917         -n|--net-settings)
918                 NETSETS=$2
919                 echo "Network Settings Configuration file: $2"
920                 shift 2
921             ;;
922         -p|--ping-site)
923                 ping_site=$2
924                 echo "Using $2 as the ping site"
925                 shift 2
926             ;;
927         -r|--resources)
928                 RESOURCES=$2
929                 echo "Deployment Resources Directory Overridden to: $2"
930                 shift 2
931             ;;
932         -v|--virtual)
933                 virtual="TRUE"
934                 echo "Executing a Virtual Deployment"
935                 shift 1
936             ;;
937         --no-ha )
938                 ha_enabled="FALSE"
939                 echo "HA Deployment Disabled"
940                 shift 1
941             ;;
942         --flat )
943                 net_isolation_enabled="FALSE"
944                 echo "Underlay Network Isolation Disabled: using flat configuration"
945                 shift 1
946             ;;
947         --no-post-config )
948                 post_config="FALSE"
949                 echo "Post install configuration disabled"
950                 shift 1
951             ;;
952         *)
953                 display_usage
954                 exit 1
955             ;;
956     esac
957   done
958
959   if [[ ! -z "$NETSETS" && "$net_isolation_enabled" == "FALSE" ]]; then
960     echo -e "${red}INFO: Single flat network requested. Ignoring any network settings!${reset}"
961   elif [[ -z "$NETSETS" && "$net_isolation_enabled" == "TRUE" ]]; then
962     echo -e "${red}ERROR: You must provide a network_settings file with -n or use --flat to force a single flat network{reset}"
963   fi
964
965   if [[ -n "$virtual" && -n "$INVENTORY_FILE" ]]; then
966     echo -e "${red}ERROR: You should not specify an inventory with virtual deployments${reset}"
967     exit 1
968   fi
969
970   if [[ ! -z "$DEPLOY_SETTINGS_FILE" && ! -f "$DEPLOY_SETTINGS_FILE" ]]; then
971     echo -e "${red}ERROR: ${DEPLOY_SETTINGS_FILE} does not exist! Exiting...${reset}"
972     exit 1
973   fi
974
975   if [[ ! -z "$NETSETS" && ! -f "$NETSETS" ]]; then
976     echo -e "${red}ERROR: ${NETSETS} does not exist! Exiting...${reset}"
977     exit 1
978   fi
979
980   if [[ ! -z "$INVENTORY_FILE" && ! -f "$INVENTORY_FILE" ]]; then
981     echo -e "{$red}ERROR: ${DEPLOY_SETTINGS_FILE} does not exist! Exiting...${reset}"
982     exit 1
983   fi
984
985   if [[ -z "$virtual" && -z "$INVENTORY_FILE" ]]; then
986     echo -e "${red}ERROR: You must specify an inventory file for baremetal deployments! Exiting...${reset}"
987     exit 1
988   fi
989 }
990
991 ##END FUNCTIONS
992
993 main() {
994   parse_cmdline "$@"
995   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
996     echo -e "${blue}INFO: Parsing network settings file...${reset}"
997     parse_network_settings
998   fi
999   if ! configure_deps; then
1000     echo -e "${red}Dependency Validation Failed, Exiting.${reset}"
1001     exit 1
1002   fi
1003   if [ -n "$DEPLOY_SETTINGS_FILE" ]; then
1004     parse_deploy_settings
1005   fi
1006   setup_instack_vm
1007   if [ "$virtual" == "TRUE" ]; then
1008     setup_virtual_baremetal
1009   elif [ -n "$INVENTORY_FILE" ]; then
1010     parse_inventory_file
1011   fi
1012   configure_undercloud
1013   undercloud_prep_overcloud_deploy
1014   if [ "$post_config" == "TRUE" ]; then
1015     if ! configure_post_install; then
1016       echo -e "${red}ERROR:Post Install Configuration Failed, Exiting.${reset}"
1017       exit 1
1018     else
1019       echo -e "${blue}INFO: Post Install Configuration Complete${reset}"
1020     fi
1021   fi
1022 }
1023
1024 main "$@"