Update (un)deploy helm plugins
[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 EOF
43 }
44
45 parse_yaml() {
46   local prefix=$2
47   local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
48   sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
49        -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p"  $1 |
50   awk -F$fs '{
51      indent = length($1)/2;
52      vname[indent] = $2;
53      for (i in vname) {if (i > indent) {delete vname[i]}}
54      if (length($3) > 0) {
55         vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
56         printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
57      }
58   }'
59 }
60
61 generate_overrides() {
62   SUBCHART_NAMES=($(cat $COMPUTED_OVERRIDES | grep -v '^\s\s'))
63
64   for index in "${!SUBCHART_NAMES[@]}"; do
65     START=${SUBCHART_NAMES[index]}
66     END=${SUBCHART_NAMES[index+1]}
67     if [[ $START == "global:" ]]; then
68       echo "global:" > $GLOBAL_OVERRIDES
69       cat $COMPUTED_OVERRIDES | sed '/common:/,/consul:/d' \
70         | sed -n '/'"$START"'/,/'log:'/p' | sed '1d;$d' >> $GLOBAL_OVERRIDES  
71     else
72       SUBCHART_DIR="$CACHE_SUBCHART_DIR/$(cut -d':' -f1 <<<"$START")"
73       if [[ -d "$SUBCHART_DIR" ]]; then
74         cat $COMPUTED_OVERRIDES | sed -n '/'"$START"'/,/'"$END"'/p' \
75           | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
76       fi
77     fi
78   done
79 }
80
81 resolve_deploy_flags() {
82   DEPLOY_FLAGS=$1
83   for flag in -f --values --set --set-string
84   do
85     while true ; do
86       # extract value of flag
87       length=${#flag}
88       length=$((length+1))
89       FLAG_VALUE="$(echo $DEPLOY_FLAGS | sed -n 's/.*\('$flag'\).\s*/\1/p' | cut -c$length- | cut -d' ' -f1)"
90
91       # purge flag and value from
92       DEPLOY_FLAGS="${DEPLOY_FLAGS//$flag $FLAG_VALUE/}"
93       DEPLOY_FLAGS=$(echo $DEPLOY_FLAGS | awk '{$1=$1};1')
94       if [ -z "$FLAG_VALUE" ] ; then
95         break
96       fi
97     done
98   done
99   echo "$DEPLOY_FLAGS"
100 }
101
102 deploy() {
103   # validate params
104   if [[ -z "$1" || -z "$2" ]]; then
105     usage
106     exit 0
107   fi
108
109   RELEASE=$1
110   CHART_URL=$2
111   FLAGS=${@:3}
112   CHART_REPO="$(cut -d'/' -f1 <<<"$CHART_URL")"
113   CHART_NAME="$(cut -d'/' -f2 <<<"$CHART_URL")"
114   CACHE_DIR=~/.helm/plugins/deploy/cache
115   CHART_DIR=$CACHE_DIR/$CHART_NAME
116   CACHE_SUBCHART_DIR=$CHART_DIR-subcharts
117   LOG_DIR=$CHART_DIR/logs
118
119   # determine if verbose output is enabled
120   VERBOSE="false"
121   if [[ $FLAGS = *"--verbose"* ]]; then
122     FLAGS="$(echo $FLAGS| sed -n 's/--verbose//p')"
123     VERBOSE="true"
124   fi
125
126   # should pass all flags instead
127   NAMESPACE="$(echo $FLAGS | sed -n 's/.*\(namespace\).\s*/\1/p' | cut -c10- | cut -d' ' -f1)"
128
129   # Remove all override values passed in as arguments. These will be used during dry run
130   # to resolve computed override values. Remaining flags will be passed on during
131   # actual upgrade/install of parent and subcharts.
132   DEPLOY_FLAGS=$(resolve_deploy_flags "$FLAGS")
133
134   # determine if upgrading individual subchart or entire parent + subcharts
135   SUBCHART_RELEASE="$(cut -d'-' -f2 <<<"$RELEASE")"
136   if [[ ! -d "$CACHE_SUBCHART_DIR/$SUBCHART_RELEASE" ]]; then
137     SUBCHART_RELEASE=
138   else
139     # update specified subchart without parent
140     RELEASE="$(cut -d'-' -f1 <<<"$RELEASE")"
141   fi
142
143   # clear previously cached charts
144   rm -rf $CACHE_DIR
145
146   # create log driectory
147   mkdir -p $LOG_DIR
148
149   # fetch umbrella chart (parent chart containing subcharts)
150   if [[ -d "$CHART_URL" ]]; then
151     mkdir -p $CHART_DIR
152     cp -R $CHART_URL/* $CHART_DIR/
153
154     charts=$CHART_DIR/charts/*
155     for subchart in $charts ; do
156       tar xzf ${subchart} -C $CHART_DIR/charts/
157     done
158     rm -rf $CHART_DIR/charts/*.tgz
159   else
160     echo "fetching $CHART_URL"
161     helm fetch $CHART_URL --untar --untardir $CACHE_DIR
162   fi
163
164   # move out subcharts to process separately
165   mkdir -p $CACHE_SUBCHART_DIR
166   mv $CHART_DIR/charts/* $CACHE_SUBCHART_DIR/
167   # temp hack - parent chart needs common subchart
168   mv $CACHE_SUBCHART_DIR/common $CHART_DIR/charts/
169
170   # disable dependencies
171   rm $CHART_DIR/requirements.lock
172   mv $CHART_DIR/requirements.yaml $CHART_DIR/requirements.deploy
173
174   # compute overrides for parent and all subcharts
175   COMPUTED_OVERRIDES=$CACHE_DIR/$CHART_NAME/computed-overrides.yaml
176   helm upgrade -i $RELEASE $CHART_DIR $FLAGS --dry-run --debug \
177    | sed -n '/COMPUTED VALUES:/,/HOOKS:/p' | sed '1d;$d' > $COMPUTED_OVERRIDES
178
179   # extract global overrides to apply to parent and all subcharts
180   GLOBAL_OVERRIDES=$CHART_DIR/global-overrides.yaml
181   generate_overrides $COMPUTED_OVERRIDES $GLOBAL_OVERRIDES
182
183   # upgrade/install parent chart first
184   if [[ -z "$SUBCHART_RELEASE" ]]; then
185     LOG_FILE=$LOG_DIR/${RELEASE}.log
186     :> $LOG_FILE
187
188     helm upgrade -i $RELEASE $CHART_DIR $DEPLOY_FLAGS -f $COMPUTED_OVERRIDES \
189      > $LOG_FILE.log 2>&1
190
191     echo "release $RELEASE deployed"
192
193     if [[ $VERBOSE == "true" ]]; then
194       cat $LOG_FILE
195     fi
196   fi
197
198   # parse computed overrides - will use to determine if a subchart is "enabled"
199   eval $(parse_yaml $COMPUTED_OVERRIDES "computed_")
200
201   # upgrade/install each "enabled" subchart
202   cd $CACHE_SUBCHART_DIR/
203   for subchart in * ; do
204     VAR="computed_${subchart}_enabled"
205     COMMAND="$"$VAR
206     eval "SUBCHART_ENABLED=$COMMAND"
207     if [[ $SUBCHART_ENABLED == "true" ]]; then
208       if [[ -z "$SUBCHART_RELEASE" || $SUBCHART_RELEASE == "$subchart" ]]; then
209         LOG_FILE=$LOG_DIR/"${RELEASE}-${subchart}".log
210         :> $LOG_FILE
211
212         SUBCHART_OVERRIDES=$CACHE_SUBCHART_DIR/$subchart/subchart-overrides.yaml
213         helm upgrade -i "${RELEASE}-${subchart}" $CACHE_SUBCHART_DIR/$subchart \
214          $DEPLOY_FLAGS -f $GLOBAL_OVERRIDES -f $SUBCHART_OVERRIDES \
215          > $LOG_FILE 2>&1
216
217         echo "release ${RELEASE}-${subchart} deployed"
218
219         if [[ $VERBOSE == "true" ]]; then
220           cat $LOG_FILE
221         fi
222       fi
223     else
224       array=($(helm ls -q | grep "${RELEASE}-${subchart}"))
225       n=${#array[*]}
226       for (( i = n-1; i >= 0; i-- )); do
227         helm del "${array[i]}" --purge
228       done
229     fi
230   done
231
232   # report on success/failures of installs/upgrades
233   helm ls | grep FAILED | grep $RELEASE
234 }
235
236 case "${1:-"help"}" in
237   "help")
238     usage
239     ;;
240   "--help")
241     usage
242     ;;
243   "-h")
244     usage
245     ;;
246   *)
247     deploy $1 $2 ${@:3}
248     ;;
249 esac
250
251 exit 0