Merge "[GENERAL] Print helm binary used"
[oom.git] / kubernetes / helm / plugins / deploy / deploy.sh
1 #!/bin/bash
2
3 usage() {
4 cat << EOF
5 Install (or upgrade) an umbrella Helm Chart, and its subcharts, as separate Helm Releases 
6
7 The umbrella Helm Chart is broken apart into a parent release and subchart releases.
8 Subcharts the are disabled (<chart>.enabled=false) will not be installed or upgraded.
9 All releases are grouped and deployed within the same namespace.
10
11
12 The deploy arguments must be a release and chart. The chart
13 argument can be either: a chart reference('stable/onap'), a path to a chart directory,
14 a packaged chart, or a fully qualified URL. For chart references, the latest
15 version will be specified unless the '--version' flag is set.
16
17 To override values in a chart, use either the '--values' flag and pass in a file
18 or use the '--set' flag and pass configuration from the command line, to force string
19 values, use '--set-string'.
20
21 You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
22 last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
23 contained a key called 'Test', the value set in override.yaml would take precedence:
24
25         $ helm deploy demo ./onap --namespace onap -f openstack.yaml -f overrides.yaml
26
27 You can specify the '--set' flag multiple times. The priority will be given to the
28 last (right-most) set specified. For example, if both 'bar' and 'newbar' values are
29 set for a key called 'foo', the 'newbar' value would take precedence:
30
31         $ helm deploy demo local/onap --namespace onap -f overrides.yaml --set log.enabled=false --set vid.enabled=false
32
33 Usage:
34   helm deploy [RELEASE] [CHART] [flags]
35
36 Flags:
37       --namespace string         namespace to install the release into. Defaults to the current kube config namespace.
38       --set stringArray          set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
39       --set-string stringArray   set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
40   -f, --values valueFiles        specify values in a YAML file or a URL(can specify multiple) (default [])
41       --verbose                  enables full helm install/upgrade output during deploy
42       --set-last-applied         set the last-applied-configuration annotation on all objects.This annotation is required to restore services using Ark/Veloro backup restore.
43 EOF
44 }
45
46 generate_overrides() {
47   SUBCHART_NAMES=($(cat $COMPUTED_OVERRIDES | grep -v '^\s\s'))
48
49   for index in "${!SUBCHART_NAMES[@]}"; do
50     START=${SUBCHART_NAMES[index]}
51     END=${SUBCHART_NAMES[index+1]}
52     if [[ $START == "global:" ]]; then
53       echo "global:" > $GLOBAL_OVERRIDES
54       cat $COMPUTED_OVERRIDES | sed '/common:/,/consul:/d' \
55         | sed -n '/^'"$START"'/,/'log:'/p' | sed '1d;$d' >> $GLOBAL_OVERRIDES
56     else
57       SUBCHART_DIR="$CACHE_SUBCHART_DIR/$(cut -d':' -f1 <<<"$START")"
58       if [[ -d "$SUBCHART_DIR" ]]; then
59         if [[ -z "$END" ]]; then
60           cat $COMPUTED_OVERRIDES | sed -n '/^'"$START"'/,/'"$END"'/p' \
61             | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
62         else
63           cat $COMPUTED_OVERRIDES | sed -n '/^'"$START"'/,/^'"$END"'/p' \
64             | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
65         fi
66       fi
67     fi
68   done
69 }
70 resolve_deploy_flags() {
71   flags=($1)
72   n=${#flags[*]}
73   for (( i = 0; i < n; i++ )); do
74     PARAM=${flags[i]}
75     if [[ $PARAM == "-f" || \
76           $PARAM == "--values" || \
77           $PARAM == "--set" || \
78           $PARAM == "--set-string" || \
79           $PARAM == "--version" ]]; then
80        # skip param and its value
81        i=$((i + 1))
82     else
83       DEPLOY_FLAGS="$DEPLOY_FLAGS $PARAM"
84     fi
85   done
86   echo "$DEPLOY_FLAGS"
87 }
88
89 deploy() {
90   # validate params
91   if [[ -z "$1" || -z "$2" ]]; then
92     usage
93     exit 0
94   fi
95
96   RELEASE=$1
97   CHART_URL=$2
98   FLAGS=${@:3}
99   CHART_REPO="$(cut -d'/' -f1 <<<"$CHART_URL")"
100   CHART_NAME="$(cut -d'/' -f2 <<<"$CHART_URL")"
101   if [[ $HELM_VER == "v3."* ]]; then
102     CACHE_DIR=~/.local/share/helm/plugins/deploy/cache
103   else
104     CACHE_DIR=~/.helm/plugins/deploy/cache
105   fi
106   echo "Use cache dir: $CACHE_DIR"
107   CHART_DIR=$CACHE_DIR/$CHART_NAME
108   CACHE_SUBCHART_DIR=$CHART_DIR-subcharts
109   LOG_DIR=$CHART_DIR/logs
110
111   # determine if verbose output is enabled
112   VERBOSE="false"
113   if [[ $FLAGS = *"--verbose"* ]]; then
114     FLAGS="$(echo $FLAGS| sed -n 's/--verbose//p')"
115     VERBOSE="true"
116   fi
117   # determine if delay for deployment is enabled
118   DELAY="false"
119   if [[ $FLAGS = *"--delay"* ]]; then
120     FLAGS="$(echo $FLAGS| sed -n 's/--delay//p')"
121     DELAY="true"
122   fi
123   # determine if set-last-applied flag is enabled
124   SET_LAST_APPLIED="false"
125   if [[ $FLAGS = *"--set-last-applied"* ]]; then
126     FLAGS="$(echo $FLAGS| sed -n 's/--set-last-applied//p')"
127     SET_LAST_APPLIED="true"
128   fi
129   if [[ $FLAGS = *"--dry-run"* ]]; then
130     VERBOSE="true"
131     FLAGS="$FLAGS --debug"
132   fi
133
134   # should pass all flags instead
135   NAMESPACE="$(echo $FLAGS | sed -n 's/.*\(namespace\).\s*/\1/p' | cut -c10- | cut -d' ' -f1)"
136
137   VERSION="$(echo $FLAGS | sed -n 's/.*\(version\).\s*/\1/p' | cut -c8- | cut -d' ' -f1)"
138
139   if [ ! -z $VERSION ]; then
140      VERSION="--version $VERSION"
141   fi
142
143   # Remove all override values passed in as arguments. These will be used during dry run
144   # to resolve computed override values. Remaining flags will be passed on during
145   # actual upgrade/install of parent and subcharts.
146   DEPLOY_FLAGS=$(resolve_deploy_flags "$FLAGS")
147
148   # determine if upgrading individual subchart or entire parent + subcharts
149   SUBCHART_RELEASE="$(cut -d'-' -f2 <<<"$RELEASE")"
150   # update specified subchart without parent
151   RELEASE="$(cut -d'-' -f1 <<<"$RELEASE")"
152   if [[ $SUBCHART_RELEASE == $RELEASE ]]; then
153     SUBCHART_RELEASE=
154   fi
155
156   # clear previously cached charts
157   rm -rf $CACHE_DIR
158
159   # fetch umbrella chart (parent chart containing subcharts)
160   if [[ -d "$CHART_URL" ]]; then
161     mkdir -p $CHART_DIR
162     cp -R $CHART_URL/* $CHART_DIR/
163
164     charts=$CHART_DIR/charts/*
165     for subchart in $charts ; do
166       tar xzf ${subchart} -C $CHART_DIR/charts/
167     done
168     rm -rf $CHART_DIR/charts/*.tgz
169   else
170     echo "fetching $CHART_URL"
171     helm fetch $CHART_URL --untar --untardir $CACHE_DIR $VERSION
172   fi
173
174   # create log driectory
175   mkdir -p $LOG_DIR
176
177   # move out subcharts to process separately
178   mkdir -p $CACHE_SUBCHART_DIR
179   mv $CHART_DIR/charts/* $CACHE_SUBCHART_DIR/
180   # temp hack - parent chart needs common subchart
181   mv $CACHE_SUBCHART_DIR/common $CHART_DIR/charts/
182
183   # disable dependencies
184   rm $CHART_DIR/requirements.lock
185   mv $CHART_DIR/requirements.yaml $CHART_DIR/requirements.deploy
186
187   # compute overrides for parent and all subcharts
188   COMPUTED_OVERRIDES=$CACHE_DIR/$CHART_NAME/computed-overrides.yaml
189   helm upgrade -i $RELEASE $CHART_DIR $FLAGS --dry-run --debug \
190    | sed -n '/COMPUTED VALUES:/,/HOOKS:/p' | sed '1d;$d' > $COMPUTED_OVERRIDES
191
192   # extract global overrides to apply to parent and all subcharts
193   GLOBAL_OVERRIDES=$CHART_DIR/global-overrides.yaml
194   generate_overrides $COMPUTED_OVERRIDES $GLOBAL_OVERRIDES
195
196   # upgrade/install parent chart first
197   if [[ -z "$SUBCHART_RELEASE" ]]; then
198     LOG_FILE=$LOG_DIR/${RELEASE}.log
199     :> $LOG_FILE
200
201     helm upgrade -i $RELEASE $CHART_DIR $DEPLOY_FLAGS -f $COMPUTED_OVERRIDES \
202      > $LOG_FILE.log 2>&1
203
204     if [[ $VERBOSE == "true" ]]; then
205       cat $LOG_FILE
206     else
207       echo "release \"$RELEASE\" deployed"
208     fi
209     # Add annotation last-applied-configuration if set-last-applied flag is set
210     if [[ $SET_LAST_APPLIED == "true" ]]; then
211       helm get manifest ${RELEASE} \
212       | kubectl apply set-last-applied --create-annotation -n onap -f - \
213       > $LOG_FILE.log 2>&1
214     fi
215   fi
216
217   # upgrade/install each "enabled" subchart
218   cd $CACHE_SUBCHART_DIR/
219   #“helm ls” is an expensive command in that it can take a long time to execute.
220   #So cache the results to prevent repeated execution.
221   ALL_HELM_RELEASES=$(helm ls -q)
222   for subchart in * ; do
223     SUBCHART_OVERRIDES=$CACHE_SUBCHART_DIR/$subchart/subchart-overrides.yaml
224
225     SUBCHART_ENABLED=0
226     if [[ -f $SUBCHART_OVERRIDES ]]; then
227       SUBCHART_ENABLED=$(cat $SUBCHART_OVERRIDES | grep -c "^enabled: true")
228     fi
229
230     if [[ $SUBCHART_ENABLED -eq 1 ]]; then
231       if [[ -z "$SUBCHART_RELEASE" || $SUBCHART_RELEASE == "$subchart" ]]; then
232         LOG_FILE=$LOG_DIR/"${RELEASE}-${subchart}".log
233         :> $LOG_FILE
234
235         helm upgrade -i "${RELEASE}-${subchart}" $CACHE_SUBCHART_DIR/$subchart \
236          $DEPLOY_FLAGS -f $GLOBAL_OVERRIDES -f $SUBCHART_OVERRIDES \
237          > $LOG_FILE 2>&1
238
239         if [[ $VERBOSE == "true" ]]; then
240           cat $LOG_FILE
241         else
242           echo "release \"${RELEASE}-${subchart}\" deployed"
243         fi
244         # Add annotation last-applied-configuration if set-last-applied flag is set
245         if [[ $SET_LAST_APPLIED == "true" ]]; then
246           helm get manifest "${RELEASE}-${subchart}" \
247           | kubectl apply set-last-applied --create-annotation -n onap -f - \
248               > $LOG_FILE.log 2>&1
249         fi
250       fi
251           if [[ $DELAY == "true" ]]; then
252                 echo sleep 3m
253                 sleep 3m
254           fi
255     else
256       array=($(echo "$ALL_HELM_RELEASES" | grep "${RELEASE}-${subchart}"))
257       n=${#array[*]}
258       for (( i = n-1; i >= 0; i-- )); do
259         if [[ $HELM_VER == "v3."* ]]; then
260           helm del "${array[i]}" 
261         else
262           helm del "${array[i]}" --purge
263         fi
264       done
265     fi
266   done
267
268   # report on success/failures of installs/upgrades
269   if [[ $HELM_VER == "v3."* ]]; then
270     helm ls --all-namespaces | grep -i FAILED | grep $RELEASE
271   else
272     helm ls | grep FAILED | grep $RELEASE
273   fi
274 }
275 HELM_VER=$(helm version --template "{{.Version}}")
276 echo $HELM_VER
277
278 case "${1:-"help"}" in
279   "help")
280     usage
281     ;;
282   "--help")
283     usage
284     ;;
285   "-h")
286     usage
287     ;;
288   *)
289     deploy $1 $2 ${@:3}
290     ;;
291 esac
292
293 exit 0