Add helm plugins to (un)deploy onap 71/67071/3
authorMike Elliott <mike.elliott@amdocs.com>
Mon, 17 Sep 2018 18:41:40 +0000 (14:41 -0400)
committerMike Elliott <mike.elliott@amdocs.com>
Mon, 17 Sep 2018 19:06:15 +0000 (15:06 -0400)
In the Casablanca release, ONAP has become very large.
Every Helm chart contains some amount of external configuration.
And unfortunately, there is a limit to the amount of configuration that
can exist in a Helm chart. When ONAP is installed as a unbrella chart
containing many subcharts (each with configuration), the
amount of configuration that resides in configmaps in K8s
causes the installation to fail. To work around this issue, it was
necessary to introiduce a Helm plugin that will install/upgrade onap
by deploying the parent chart and each subchart within its own
Helm "release". This is the initial version of the plugins, which
has been verified to work and unblock integration in the deployment
of all of ONAP. Improvements will be made post M4 to further harden
and enhance the plugins. Specifically, the plugins are not currently
resilent to network issues which can cause some of the subcharts to
fail to deploy. To work around this, the plugins should be run from
within the same network as the k8s cluster you are deploying to.

To install, copy plugins directory into your local ~/.helm/ folder.
After which you should see 'deploy' and 'undeploy' if you do a 'helm'
with no arguments.

Change-Id: I7c586f1c75f7249d2d7c38b4088129162c96401d
Issue-ID: OOM-1344
Signed-off-by: Mike Elliott <mike.elliott@amdocs.com>
kubernetes/helm/plugins/deploy/deploy.sh [new file with mode: 0755]
kubernetes/helm/plugins/deploy/plugin.yaml [new file with mode: 0644]
kubernetes/helm/plugins/undeploy/plugin.yaml [new file with mode: 0644]
kubernetes/helm/plugins/undeploy/undeploy.sh [new file with mode: 0755]

diff --git a/kubernetes/helm/plugins/deploy/deploy.sh b/kubernetes/helm/plugins/deploy/deploy.sh
new file mode 100755 (executable)
index 0000000..07455d7
--- /dev/null
@@ -0,0 +1,168 @@
+#!/bin/bash
+
+usage() {
+cat << EOF
+Install (or upgrade) an umbrella Helm Chart, and its subcharts, as separate Helm Releases 
+
+The umbrella Helm Chart is broken apart into a parent release and subchart releases.
+Subcharts the are disabled (<chart>.enabled=false) will not be installed or upgraded.
+All releases are grouped and deployed within the same namespace.
+
+
+The deploy arguments must be a release and chart. The chart
+argument can be either: a chart reference('stable/onap'), a path to a chart directory,
+a packaged chart, or a fully qualified URL. For chart references, the latest
+version will be specified unless the '--version' flag is set.
+
+To override values in a chart, use either the '--values' flag and pass in a file
+or use the '--set' flag and pass configuration from the command line, to force string
+values, use '--set-string'.
+
+You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
+last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
+contained a key called 'Test', the value set in override.yaml would take precedence:
+
+       $ helm deploy demo ./onap --namespace onap -f openstack.yaml -f overrides.yaml
+
+You can specify the '--set' flag multiple times. The priority will be given to the
+last (right-most) set specified. For example, if both 'bar' and 'newbar' values are
+set for a key called 'foo', the 'newbar' value would take precedence:
+
+       $ helm deploy demo local/onap --namespace onap -f overrides.yaml --set log.enabled=false --set vid.enabled=false
+
+Usage:
+  helm deploy [RELEASE] [CHART] [flags]
+
+Flags:
+      --namespace string         namespace to install the release into. Defaults to the current kube config namespace.
+      --set stringArray          set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
+      --set-string stringArray   set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
+  -f, --values valueFiles        specify values in a YAML file or a URL(can specify multiple) (default [])
+EOF
+}
+
+parse_yaml() {
+  local prefix=$2
+  local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
+  sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
+       -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p"  $1 |
+  awk -F$fs '{
+     indent = length($1)/2;
+     vname[indent] = $2;
+     for (i in vname) {if (i > indent) {delete vname[i]}}
+     if (length($3) > 0) {
+        vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
+        printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
+     }
+  }'
+}
+
+generate_overrides() {
+  SUBCHART_NAMES=($(cat $COMPUTED_OVERRIDES | grep -v '^\s\s'))
+
+  for index in "${!SUBCHART_NAMES[@]}"; do
+    START=${SUBCHART_NAMES[index]}
+    END=${SUBCHART_NAMES[index+1]}
+    if [[ $START == "global:" ]]; then
+      echo "global:" > $GLOBAL_OVERRIDES
+      cat $COMPUTED_OVERRIDES | sed '/common:/,/consul:/d' \
+        | sed -n '/'"$START"'/,/'log:'/p' | sed '1d;$d' >> $GLOBAL_OVERRIDES  
+    else
+      SUBCHART_DIR="$CACHE_SUBCHART_DIR/$(cut -d':' -f1 <<<"$START")"
+      if [[ -d "$SUBCHART_DIR" ]]; then
+        cat $COMPUTED_OVERRIDES | sed -n '/'"$START"'/,/'"$END"'/p' \
+          | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
+      fi
+    fi
+  done
+}
+
+deploy() {
+  RELEASE=$1
+  CHART_URL=$2
+  FLAGS=${@:3}
+  CHART_REPO="$(cut -d'/' -f1 <<<"$CHART_URL")"
+  CHART_NAME="$(cut -d'/' -f2 <<<"$CHART_URL")"
+  CACHE_DIR=~/.helm/plugins/deploy/cache
+  CHART_DIR=$CACHE_DIR/$CHART_NAME
+  CACHE_SUBCHART_DIR=$CHART_DIR-subcharts
+  # should pass all flags instead
+  NAMESPACE="$(echo $FLAGS | sed -n 's/.*\(namespace\).\s*/\1/p' | cut -c10-)"
+  # clear previously cached charts
+  rm -rf $CACHE_DIR
+
+  # fetch umbrella chart (parent chart containing subcharts)
+  if [[ -d "$CHART_URL" ]]; then
+    mkdir -p $CHART_DIR
+    cp -R $CHART_URL/* $CHART_DIR/
+
+    cd $CHART_DIR/charts/
+    for subchart in * ; do
+      tar xzf ${subchart}
+    done
+    rm -rf *.tgz
+  else
+    helm fetch $CHART_URL --untar --untardir $CACHE_DIR
+  fi
+
+  # move out subcharts to process separately
+  mkdir -p $CACHE_SUBCHART_DIR
+  mv $CHART_DIR/charts/* $CACHE_SUBCHART_DIR/
+  # temp hack - parent chart needs common subchart
+  mv $CACHE_SUBCHART_DIR/common $CHART_DIR/charts/
+
+  # disable dependencies
+  rm $CHART_DIR/requirements.lock
+  mv $CHART_DIR/requirements.yaml $CHART_DIR/requirements.deploy
+
+  # compute overrides for parent and all subcharts
+  COMPUTED_OVERRIDES=$CACHE_DIR/$CHART_NAME/computed-overrides.yaml
+  helm upgrade -i $RELEASE $CHART_DIR $FLAGS --dry-run --debug \
+   | sed -n '/COMPUTED VALUES:/,/HOOKS:/p' | sed '1d;$d' > $COMPUTED_OVERRIDES
+
+  # extract global overrides to apply to parent and all subcharts
+  GLOBAL_OVERRIDES=$CHART_DIR/global-overrides.yaml
+  generate_overrides $COMPUTED_OVERRIDES $GLOBAL_OVERRIDES
+
+  # upgrade/install parent chart first
+  helm upgrade -i $RELEASE $CHART_DIR --namespace $NAMESPACE -f $COMPUTED_OVERRIDES
+
+  # parse computed overrides - will use to determine if a subchart is "enabled"
+  eval $(parse_yaml $COMPUTED_OVERRIDES "computed_")
+
+  # upgrade/install each "enabled" subchart
+  cd $CACHE_SUBCHART_DIR
+  for subchart in * ; do
+    VAR="computed_${subchart}_enabled"
+    COMMAND="$"$VAR
+    eval "SUBCHART_ENABLED=$COMMAND"
+    if [[ $SUBCHART_ENABLED == "true" ]]; then
+      SUBCHART_OVERRIDES=$CACHE_SUBCHART_DIR/$subchart/subchart-overrides.yaml
+      helm upgrade -i "${RELEASE}-${subchart}" $CACHE_SUBCHART_DIR/$subchart \
+       --namespace $NAMESPACE -f $GLOBAL_OVERRIDES -f $SUBCHART_OVERRIDES
+    fi
+  done
+}
+
+if [[ $# < 2 ]]; then
+  usage
+  exit 0
+fi
+
+case "${1:-"help"}" in
+  "help")
+    usage
+    ;;
+  "--help")
+    usage
+    ;;
+  "-h")
+    usage
+    ;;
+  *)
+    deploy $1 $2 ${@:3}
+    ;;
+esac
+
+exit 0
\ No newline at end of file
diff --git a/kubernetes/helm/plugins/deploy/plugin.yaml b/kubernetes/helm/plugins/deploy/plugin.yaml
new file mode 100644 (file)
index 0000000..fc7f7d0
--- /dev/null
@@ -0,0 +1,7 @@
+name: "deploy"
+version: "1.0.0"
+usage: "install (upgrade if release exists) parent chart and subcharts as separate 
+but related releases"
+description: "install (upgrade if release exists) parent charty and all subcharts as separate 
+but related releases"
+command: "$HELM_PLUGIN_DIR/deploy.sh"
\ No newline at end of file
diff --git a/kubernetes/helm/plugins/undeploy/plugin.yaml b/kubernetes/helm/plugins/undeploy/plugin.yaml
new file mode 100644 (file)
index 0000000..02999fd
--- /dev/null
@@ -0,0 +1,7 @@
+name: "undeploy"
+version: "1.0.0"
+usage: "delete parent chart and subcharts that were deployed as separate 
+releases"
+description: "delete parent chart and subcharts that were deployed as separate 
+releases"
+command: "$HELM_PLUGIN_DIR/undeploy.sh"
\ No newline at end of file
diff --git a/kubernetes/helm/plugins/undeploy/undeploy.sh b/kubernetes/helm/plugins/undeploy/undeploy.sh
new file mode 100755 (executable)
index 0000000..02b5d34
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+usage() {
+cat << EOF
+Delete an umbrella Helm Chart, and its subcharts, that was previously deployed using 'Helm deploy'. 
+
+Example of deleting all Releases that have the prefix 'demo'.
+  $ helm undeploy demo
+
+  $ helm undeploy demo --purge
+
+Usage:
+  helm undeploy [RELEASE] [flags]
+
+Flags:
+      --purge     remove the releases from the store and make its name free for later use
+EOF
+}
+
+undeploy() {
+  RELEASE=$1
+  FLAGS=$2
+
+  array=($(helm ls -q | grep $RELEASE))
+  n=${#array[*]}
+  for (( i = n-1; i >= 0; i-- ))
+  do
+    helm del "${array[i]}" $FLAGS
+  done
+}
+
+if [[ $# < 1 ]]; then
+  echo "Error: command 'undeploy' requires a release name"
+  exit 0
+fi
+
+case "${1:-"help"}" in
+  "help")
+    usage
+    ;;
+  "--help")
+    usage
+    ;;
+  "-h")
+    usage
+    ;;
+  *)
+    undeploy $1 ${@:2}
+    ;;
+esac
+
+exit 0
\ No newline at end of file