Set proper defaults for etcd configuration
[multicloud/k8s.git] / kud / tests / _functions.sh
1 #!/bin/bash
2 # SPDX-license-identifier: Apache-2.0
3 ##############################################################################
4 # Copyright (c) 2018
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
10
11 set -o errexit
12 set -o nounset
13 set -o pipefail
14
15 FUNCTIONS_DIR="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
16
17 source /etc/environment
18
19 function print_msg {
20     local msg=$1
21     local RED='\033[0;31m'
22     local NC='\033[0m'
23
24     echo -e "${RED} $msg ---------------------------------------${NC}"
25 }
26
27 function get_ovn_central_address {
28     #Reuse OVN_CENTRAL_ADDRESS if available (bypassable by --force flag)
29     if [[ "${1:-}" != "--force" ]] && [[ -n "${OVN_CENTRAL_ADDRESS:-}" ]]; then
30         echo "${OVN_CENTRAL_ADDRESS}"
31         return 0
32     fi
33
34     local remote_command="ip address show dev $OVN_CENTRAL_INTERFACE primary"
35     declare -a ansible_command=(ansible ovn-central[0] -i \
36                 "${FUNCTIONS_DIR}/../hosting_providers/vagrant/inventory/hosts.ini")
37     declare -a filter=(awk -F '[ \t/]+' \
38                 'BEGIN {r=1} {for (i=1; i<=NF; i++) if ($i == "inet") {print $(i+1); r=0}} END {exit r}')
39     local result
40
41     #Determine OVN_CENTRAL_INTERFACE address
42     if ! result="$("${ansible_command[@]}" -a "${remote_command}")"; then
43         echo "Ansible error for remote host ovn-central[0]" >&2
44         return 1
45     else
46         if [[ "${result}" != *CHANGED* ]]; then
47             echo "Failed to execute command on remote host ovn-central[0]" >&2
48             return 2
49         else
50             if ! result="$("${filter[@]}" <<< "${result}")"; then
51                 echo "Failed to retrieve interface address from command output" >&2
52                 return 3
53             else
54                 echo "${result}:6641"
55             fi
56         fi
57     fi
58 }
59
60 function call_api {
61     #Runs curl with passed flags and provides
62     #additional error handling and debug information
63
64     #Function outputs server response body
65     #and performs validation of http_code
66
67     local status
68     local curl_response_file="$(mktemp -p /tmp)"
69     local curl_common_flags=(-s -w "%{http_code}" -o "${curl_response_file}")
70     local command=(curl "${curl_common_flags[@]}" "$@")
71
72     echo "[INFO] Running '${command[@]}'" >&2
73     if ! status="$("${command[@]}")"; then
74         echo "[ERROR] Internal curl error! '$status'" >&2
75         cat "${curl_response_file}"
76         rm "${curl_response_file}"
77         return 2
78     else
79         echo "[INFO] Server replied with status: ${status}" >&2
80         cat "${curl_response_file}"
81         rm "${curl_response_file}"
82         if [[ "${status:0:1}" =~ [45] ]]; then
83             return 1
84         else
85             return 0
86         fi
87     fi
88 }
89
90 function delete_resource {
91     #Issues DELETE http call to provided endpoint
92     #and further validates by following GET request
93
94     call_api -X DELETE "$1"
95     ! call_api -X GET "$1" >/dev/null
96 }
97
98 # init_network() - This function creates the OVN resouces required by the test
99 function init_network {
100     local fname=$1
101     local router_name="ovn4nfv-master"
102
103     name=$(cat $fname | yq '.spec.name' | xargs)
104     subnet=$(cat $fname  | yq '.spec.subnet' | xargs)
105     gateway=$(cat $fname  | yq '.spec.gateway' | xargs)
106     ovn_central_address=$(get_ovn_central_address)
107
108     router_mac=$(printf '00:00:00:%02X:%02X:%02X' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))
109     ovn-nbctl --may-exist --db tcp:$ovn_central_address ls-add $name -- set logical_switch $name other-config:subnet=$subnet external-ids:gateway_ip=$gateway
110     ovn-nbctl --may-exist --db tcp:$ovn_central_address lrp-add $router_name rtos-$name $router_mac $gateway
111     ovn-nbctl --may-exist --db tcp:$ovn_central_address lsp-add $name stor-$name -- set logical_switch_port stor-$name type=router options:router-port=rtos-$name addresses=\"$router_mac\"
112 }
113
114 # cleanup_network() - This function removes the OVN resources created for the test
115 function cleanup_network {
116     local fname=$1
117
118     name=$(cat $fname | yq '.spec.name' | xargs)
119     ovn_central_address=$(get_ovn_central_address)
120
121     for cmd in "ls-del $name" "lrp-del rtos-$name" "lsp-del stor-$name"; do
122         ovn-nbctl --if-exist --db tcp:$ovn_central_address $cmd
123     done
124 }
125
126 function _checks_args {
127     if [[ -z $1 ]]; then
128         echo "Missing CSAR ID argument"
129         exit 1
130     fi
131     if [[ -z $CSAR_DIR ]]; then
132         echo "CSAR_DIR global environment value is empty"
133         exit 1
134     fi
135     mkdir -p ${CSAR_DIR}/${1}
136 }
137
138 # destroy_deployment() - This function ensures that a specific deployment is
139 # destroyed in Kubernetes
140 function destroy_deployment {
141     local deployment_name=$1
142
143     echo "$(date +%H:%M:%S) - $deployment_name : Destroying deployment"
144     kubectl delete deployment $deployment_name --ignore-not-found=true --now
145     while kubectl get deployment $deployment_name &>/dev/null; do
146         echo "$(date +%H:%M:%S) - $deployment_name : Destroying deployment"
147     done
148 }
149
150 # recreate_deployment() - This function destroys an existing deployment and
151 # creates an new one based on its yaml file
152 function recreate_deployment {
153     local deployment_name=$1
154
155     destroy_deployment $deployment_name
156     kubectl create -f $deployment_name.yaml
157 }
158
159 # wait_deployment() - Wait process to Running status on the Deployment's pods
160 function wait_deployment {
161     local deployment_name=$1
162
163     status_phase=""
164     while [[ $status_phase != "Running" ]]; do
165         new_phase=$(kubectl get pods | grep  $deployment_name | awk '{print $3}')
166         if [[ $new_phase != $status_phase ]]; then
167             echo "$(date +%H:%M:%S) - $deployment_name : $new_phase"
168             status_phase=$new_phase
169         fi
170         if [[ $new_phase == "Err"* ]]; then
171             exit 1
172         fi
173     done
174 }
175
176 # wait_for_pod() - Wait until first pod matched by kubectl filters is in running status
177 function wait_for_pod {
178     #Example usage:
179     # wait_for_pods example_pod
180     # wait_for_pods --namespace test different_pod
181     # wait_for_pods -n test -l app=plugin_test
182
183     status_phase=""
184     while [[ "$status_phase" != "Running" ]]; do
185         new_phase="$(kubectl get pods -o 'go-template={{ index .items 0 "status" "phase" }}' "$@" )"
186         if [[ "$new_phase" != "$status_phase" ]]; then
187             echo "$(date +%H:%M:%S) - Filter=[$*] : $new_phase"
188             status_phase="$new_phase"
189         fi
190         if [[ "$new_phase" == "Err"* ]]; then
191             exit 1
192         fi
193     done
194 }
195
196 # setup() - Base testing setup shared among functional tests
197 function setup {
198     if ! $(kubectl version &>/dev/null); then
199         echo "This funtional test requires kubectl client"
200         exit 1
201     fi
202     for deployment_name in $@; do
203         recreate_deployment $deployment_name
204     done
205     sleep 5
206     for deployment_name in $@; do
207         wait_deployment $deployment_name
208     done
209 }
210
211 # teardown() - Base testing teardown function
212 function teardown {
213     for deployment_name in $@; do
214         destroy_deployment $deployment_name
215     done
216 }
217 test_folder=${FUNCTIONS_DIR}