Generalization of recursive function
[apex.git] / ci / util.sh
1 #!/usr/bin/env bash
2 # Utility script used to interact with a deployment
3 # @author Tim Rozet (trozet@redhat.com)
4
5 VALID_CMDS="undercloud overcloud opendaylight debug-stack mock-detached -h --help"
6 SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
7
8 ##connects to undercloud
9 ##params: user to login with, command to execute on undercloud (optional)
10 function undercloud_connect {
11   local user=$1
12
13   if [ -z "$1" ]; then
14     echo "Missing required argument: user to login as to undercloud"
15     return 1
16   fi
17
18   if [ -z "$2" ]; then
19     ssh ${SSH_OPTIONS[@]} ${user}@$(get_undercloud_ip)
20   else
21     ssh ${SSH_OPTIONS[@]} -T ${user}@$(get_undercloud_ip) "$2"
22   fi
23 }
24
25 ##outputs the Undercloud's IP address
26 ##params: none
27 function get_undercloud_ip {
28   echo $(arp -an | grep $(virsh domiflist undercloud | grep default |\
29     awk '{print $5}') | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
30 }
31
32 ##connects to overcloud nodes
33 ##params: node to login to, command to execute on overcloud (optional)
34 function overcloud_connect {
35   local node
36   local node_output
37   local node_ip
38
39   if [ -z "$1" ]; then
40     echo "Missing required argument: overcloud node to login to"
41     return 1
42   elif ! echo "$1" | grep -E "(controller|compute)[0-9]+" > /dev/null; then
43     echo "Invalid argument: overcloud node to login to must be in the format: \
44 controller<number> or compute<number>"
45     return 1
46   fi
47
48   node_output=$(undercloud_connect "stack" "source stackrc; nova list")
49   node=$(echo "$1" | sed -E 's/([a-zA-Z]+)([0-9]+)/\1-\2/')
50
51   node_ip=$(echo "$node_output" | grep "$node" | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
52
53   if [ "$node_ip" == "" ]; then
54     echo -e "Unable to find IP for ${node} in \n${node_output}"
55     return 1
56   fi
57
58   if [ -z "$2" ]; then
59     ssh ${SSH_OPTIONS[@]} heat-admin@${node_ip}
60   else
61     ssh ${SSH_OPTIONS[@]} -T heat-admin@${node_ip} "$2"
62   fi
63 }
64
65 ##connects to opendaylight karaf console
66 ##params: None
67 function opendaylight_connect {
68   local opendaylight_ip
69   opendaylight_ip=$(undercloud_connect "stack" "cat overcloudrc | grep SDN_CONTROLLER_IP | grep -Eo [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
70
71   if [ "$opendaylight_ip" == "" ]; then
72     echo -e "Unable to find IP for OpenDaylight in overcloudrc"
73     return 1
74   else
75     echo -e "Connecting to ODL Karaf console.  Default password is 'karaf'"
76   fi
77
78   ssh -p 8101 ${SSH_OPTIONS[@]} karaf@${opendaylight_ip}
79 }
80
81 ##outputs heat stack deployment failures
82 ##params: none
83 function debug_stack {
84   source ~/stackrc
85   openstack stack failures list overcloud --long
86 }
87
88 resolve_cmd() {
89   local given=$1
90   shift
91   local list=($*)
92   local inv=(${list[*]##${given}*})
93   local OIFS=$IFS; IFS='|'; local pat="${inv[*]}"; IFS=$OIFS
94   shopt -s extglob
95   echo "${list[*]##+($pat)}"
96   shopt -u extglob
97 }
98
99 display_usage() {
100   echo -e "Usage:\n$0 subcommand [ arguments ]\n"
101   echo -e "Arguments:\n"
102   echo -e "   undercloud [ user [ command ] ]   Connect to Undercloud VM as user and optionally execute a command"
103   echo -e "                                     user    Optional: Defaults to 'stack'"
104   echo -e "                                     command Optional: Defaults to none"
105   echo -e ""
106   echo -e "   opendaylight                      Connect to OpenDaylight Karaf console"
107   echo -e ""
108   echo -e "   overcloud  [ node [ command ] ]   Connect to an Overcloud node and optionally execute a command"
109   echo -e "                                     node    Required: in format controller|compute<number>.  Example: controller0"
110   echo -e "                                     command Optional: Defaults to none"
111   echo -e ""
112   echo -e "   debug-stack                       Print parsed deployment failures to stdout"
113   echo -e ""
114   echo -e "   mock-detached on | off            Add firewall rules to the jump host to mock a detached deployment\n"
115 }
116
117 ##translates the command line argument
118 ##params: $@ the entire command line is passed
119 ##usage: parse_cmd_line() "$@"
120 parse_cmdline() {
121   local match
122
123   match=($(resolve_cmd $1 $VALID_CMDS))
124   if [ ${#match[*]} -gt 1 ]; then
125     echo "$1 is ambiguous, possible matches: ${match[*]}" >&2
126     exit 1
127   elif [ ${#match[*]} -lt 1 ]; then
128     echo "$1 is not a recognized command.  Use -h to see acceptable list" >&2
129     exit 1
130   else
131     match=$(echo $match | tr -d ' ')
132   fi
133
134   case "$match" in
135         -h|--help)
136                 display_usage
137                 exit 0
138             ;;
139         undercloud)
140                 if [ -z "$2" ]; then
141                   # connect as stack by default
142                   undercloud_connect stack
143                 elif [ -z "$3" ]; then
144                   undercloud_connect "$2"
145                 else
146                   undercloud_connect "$2" "$3"
147                 fi
148                 exit 0
149             ;;
150         overcloud)
151                 if [ -z "$2" ]; then
152                   overcloud_connect
153                 elif [ -z "$3" ]; then
154                   overcloud_connect "$2"
155                 else
156                   overcloud_connect "$2" "$3"
157                 fi
158                 exit 0
159             ;;
160         opendaylight)
161                 opendaylight_connect
162                 exit 0
163             ;;
164         debug-stack)
165                 undercloud_connect stack "$(typeset -f debug_stack); debug_stack"
166                 exit 0
167             ;;
168         mock-detached)
169                 if [ "$2" == "on" ]; then
170                     echo "Ensuring we can talk to gerrit.opnfv.org"
171                     iptables -A OUTPUT -p tcp -d gerrit.opnfv.org --dport 443 -j ACCEPT
172                     echo "Blocking output http (80) traffic"
173                     iptables -A OUTPUT -p tcp --dport 80 -j REJECT
174                     iptables -A FORWARD -p tcp --dport 80 -j REJECT
175                     echo "Blocking output https (443) traffic"
176                     iptables -A OUTPUT -p tcp --dport 443 -j REJECT
177                     iptables -A FORWARD -p tcp --dport 443 -j REJECT
178                     echo "Blocking output dns (53) traffic"
179                     iptables -A FORWARD -p tcp --dport 53 -j REJECT
180                 elif [ "$2" == "off" ]; then
181                     echo "Cleaning gerrit.opnfv.org specific rule"
182                     iptables -D OUTPUT -p tcp -d gerrit.opnfv.org --dport 443 -j ACCEPT
183                     echo "Allowing output http (80) traffic"
184                     iptables -D OUTPUT -p tcp --dport 80 -j REJECT
185                     iptables -D FORWARD -p tcp --dport 80 -j REJECT
186                     echo "Allowing output https (443) traffic"
187                     iptables -D OUTPUT -p tcp --dport 443 -j REJECT
188                     iptables -D FORWARD -p tcp --dport 443 -j REJECT
189                     echo "Allowing output dns (53) traffic"
190                     iptables -D OUTPUT -p tcp --dport 53 -j REJECT
191                     iptables -D FORWARD -p tcp --dport 53 -j REJECT
192                 else
193                     display_usage
194                 fi
195                 exit 0
196             ;;
197         *)
198                 echo -e "\n\nThis script is used to interact with Apex deployments\n\n"
199                 echo "Use -h to display help"
200                 exit 1
201             ;;
202   esac
203 }
204
205
206 main() {
207   parse_cmdline "$@"
208 }
209
210 main "$@"