#!/bin/bash
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0

# Helm chart inflator
#
# Reads a file like this
#
#  apiVersion: kustomize.config.k8s.io/v1
#  kind: ChartInflator
#  metadata:
#    name: notImportantHere
#  chartName: nameOfStableChart
#  values: /abs/path/to/local/values/file
#  chartHome: /abs/path/local/chart/storage
#  chartRelease: (stable|incubator)
#  chartVersion: 9.0.1
#  helmHome: /abs/path/to/helm/config
#  helmBin: /abs/path/to/helmBin
#  releaseName: nameOfHelmRelease
#  releaseNamespace: namespaceWhereHelmWouldApply
#
# fetches the given chart from stable/$chartName,
# and inflates it to stdout, using the given values file.
#
# chartDir default: $TMP_DIR/charts
#
# Example execution:
# ./plugin/someteam.example.com/v1/ChartInflator configFile.yaml

set -e

# Yaml parsing is a ridiculous thing to do in bash,
# but let's try:
function parseYaml {
  local file=$1
  while read -r line
  do
    local k=${line%%:*}
    local v=${line#*:}

    [ "$k" == "chartName" ] && chartName=$v
    [ "$k" == "chartRepo" ] && chartRepo=$v
    [ "$k" == "chartHome" ] && chartHome=$v
    [ "$k" == "chartRelease" ] && chartRelease=$v
    [ "$k" == "chartVersion" ] && chartVersion=$v
    [ "$k" == "values" ] && valuesFile=$v
    [ "$k" == "helmHome" ] && helmHome=$v
    [ "$k" == "helmBin" ] && helmBin=$v
    [ "$k" == "releaseName" ] && releaseName=$v
    [ "$k" == "releaseNamespace" ] && releaseNamespace=$v
  done <"$file"

  # Trim leading space
  chartName="${chartName#"${chartName%%[![:space:]]*}"}"
  chartRepo="${chartRepo#"${chartRepo%%[![:space:]]*}"}"
  chartHome="${chartHome#"${chartHome%%[![:space:]]*}"}"
  chartRelease="${chartRelease#"${chartRelease%%[![:space:]]*}"}"
  chartVersion="${chartVersion#"${chartVersion%%[![:space:]]*}"}"
  valuesFile="${valuesFile#"${valuesFile%%[![:space:]]*}"}"
  helmBin="${helmBin#"${helmBin%%[![:space:]]*}"}"
  releaseName="${releaseName#"${releaseName%%[![:space:]]*}"}"
  releaseNamespace="${releaseNamespace#"${releaseNamespace%%[![:space:]]*}"}"
}

TMP_DIR=$(mktemp -d)

parseYaml $1

# Where all the files generated by 'helm init' live.
if [ -z "$helmHome" ]; then
  helmHome=$TMP_DIR/dotHelm
fi

# Where helm charts are unpacked.
if [ -z "$chartHome" ]; then
  chartHome=$TMP_DIR/charts
fi

# Set default chartRelease to "stable"
if [ -z "$chartRelease" ]; then
  chartRelease="stable"
fi

# The repo to pull the chart from
if [ -n "$chartRepo" ]; then
  chartRepoArg="--repo=$chartRepo"
  chartNameArg="$chartName"
else
  chartNameArg="$chartRelease/$chartName"
fi

# Set version only if specified
if [ ! -z "$chartVersion" ]; then
  chartVersionArg="--version=$chartVersion"
fi

if [ -z "$helmBin" ]; then
  helmBin=helm
fi

if [ -z "$valuesFile" ]; then
  valuesFile=$chartHome/$chartName/values.yaml
fi

if [ -z "$releaseName" ]; then
  releaseName=release-name
fi

if [ -z "$releaseNamespace" ]; then
  releaseNamespace=default
fi

function v2RunHelm {
  $helmBin --home $helmHome "$@"
}

function v3RunHelm {
  XDG_CONFIG_DIR=$helmHome
  $helmBin "$@"
}

function v2InitHelm {
  # The init command is extremely chatty
  v2RunHelm init --client-only >& /dev/null
}

function v3InitHelm {
  # Do nothing - there's no init command in helm v3
  true
}

function v2PullChart {
  if [ ! -d "$chartHome/$chartName" ]; then
    v2RunHelm fetch $chartVersionArg \
        $chartRepoArg \
        --untar \
        --untardir $chartHome \
        $chartNameArg
  fi
}

function v3PullChart {
  if [ ! -d "$chartHome/$chartName" ]; then
    v3RunHelm pull $chartVersionArg \
        $chartRepoArg \
        --untar \
        --untardir $chartHome \
        $chartNameArg
  fi
}

function v2InflateChart {
  v2RunHelm template \
      --name $releaseName \
      --namespace $releaseNamespace \
      --values $valuesFile \
      $chartHome/$chartName
}

function v3InflateChart {
    v3RunHelm template \
      --release-name $releaseName \
      --namespace $releaseNamespace \
      --values $valuesFile \
      $chartHome/$chartName

}

HELM_VERSION=$($helmBin version -c --short)

case $HELM_VERSION in
  'Client: v2'*)
    v2InitHelm
    v2PullChart
    v2InflateChart
  ;;
  v3*)
    v3InitHelm
    v3PullChart
    v3InflateChart
  ;;
  *)
    echo "[!] Unsupported 'helm' version '${HELM_VERSION}'" 1>&2 && exit 1
  ;;
esac

/bin/rm -rf $TMP_DIR
