Skip to content

Commit

Permalink
feat: implement 'downloader'
Browse files Browse the repository at this point in the history
Signed-off-by: Julien Bouyoud <jBouyoud@users.noreply.github.com>
  • Loading branch information
jBouyoud committed Nov 11, 2020
1 parent 52b36ae commit 9e8de56
Show file tree
Hide file tree
Showing 31 changed files with 633 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/tests/coverage/
/node_modules/
/repository/
/.bin/
6 changes: 6 additions & 0 deletions plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ usage: 'Repeatable configuration scheme for Helm Charts'
description: 'This plugin provides a convenient way to manage a set of configuration scheme'
useTunnel: false
command: '$HELM_PLUGIN_DIR/scripts/run.sh'

hooks:
install: '$HELM_PLUGIN_DIR/scripts/wrapper/run.cmd $HELM_PLUGIN_DIR/scripts/install.sh'
update: '$HELM_PLUGIN_DIR/scripts/wrapper/run.cmd $HELM_PLUGIN_DIR/scripts/install.sh'

platformCommand:
- os: windows
command: 'cmd /c $HELM_PLUGIN_DIR/scripts/wrapper/sh.cmd $HELM_PLUGIN_DIR/scripts/run.sh'

downloaders:
- command: 'scripts/run.sh downloader'
protocols:
Expand Down
72 changes: 72 additions & 0 deletions scripts/commands/downloader.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env sh

set -eu

# Create temporary directory
TMP_DIR="${HELM_CONFIG_SCHEME_TMP_DIR:-$(mktemp -d)}"

YQ_PATH="${HELM_PLUGIN_DIR}/.bin/"

_trap_hook() {
unset_subst_args
rm -rf "${TMP_DIR}"
}

_yq() {
if [ -f "${YQ_PATH}/yq" ]; then
"${YQ_PATH}/yq" "$@"
else
"${YQ_PATH}/yq.exe" "$@"
fi
}

downloader() {
if [ $# -ne 2 ]; then
log_error "[downloader] Not able to download config, missing args"
exit 2
fi
uri="${1}"
parent_process_cmd_line="${2}"

case "${uri}" in
"config://"*) ;;

*)
log_error "[downloader] URI '${uri}' not supported"
exit 2
;;
esac

scheme_name=$(printf '%s' "${uri}" | sed 's!config://!!')

if ! repository_scheme_exists "${scheme_name}"; then
log_error "[downloader] Scheme '${scheme_name}' doesn't exists"
exit 2
fi

# build parameters
export_subst_args "${parent_process_cmd_line}"

idx=0
repository_view_scheme "${scheme_name}" | while read -r file_template; do
log_info "[downloader] Looking for '${file_template}'..."

eval "file=${file_template}"
# shellcheck disable=SC2154
file_content="$( (_file_get "${file}" || printf ''))"

if [ -z "${file_content}" ]; then
log_info "[downloader] Ignored config source : ${file}"
else
log_info "[downloader] Loaded config source : ${file}"
printf '%s\n' "${file_content}" >"${TMP_DIR}/file-${idx}"
idx=$((idx + 1))
fi
done

if [ "$(find "${TMP_DIR}" -type f | wc -l)" -le 1 ]; then
cat "${TMP_DIR}/file-0" 2>/dev/null || printf ''
else
_yq merge -x "${TMP_DIR}"/file-*
fi
}
101 changes: 101 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env sh

set -eu

# Path to current directory
SCRIPT_DIR="$(dirname "$0")"

if [ "$(uname)" = "Darwin" ]; then
if ! command -v realpath >/dev/null; then
brew install coreutils
fi
fi

YQ_PATH="${HELM_PLUGIN_DIR}/.bin/"
mkdir -p "${YQ_PATH}"

YQ_DEFAULT_VERSION="3.4.1"
YQ_VERSION="${YQ_VERSION:-"${YQ_DEFAULT_VERSION}"}"

YQ_PLATFORM="windows"
if [ "$(uname)" = "Darwin" ]; then
YQ_PLATFORM="darwin"
elif [ "$(uname)" = "Linux" ]; then
YQ_PLATFORM="linux"
fi

YQ_ARCH="386"
if [ "$(uname -m)" = "x86_64" ]; then
YQ_ARCH="amd64"
fi

YQ_SUFFIX=""
if [ "${YQ_PLATFORM}" = "windows" ]; then
YQ_SUFFIX=".exe"
fi

YQ_URL="${YQ_URL:-"https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_${YQ_PLATFORM}_${YQ_ARCH}${YQ_SUFFIX}"}"

# shellcheck disable=SC2034
YQ_SHA_darwin_amd64="5553d4640550debed5213a5eb6016d3a3485ca8a36e9c71996610280755d5a50"
# shellcheck disable=SC2034
YQ_SHA_linux_368="ba57700f41cf21bf019af0eec47cf9884f70c25bc5abb0f3347bd42f19609739"
# shellcheck disable=SC2034
YQ_SHA_linux_amd64="adbc6dd027607718ac74ceac15f74115ac1f3caef68babfb73246929d4ffb23c"
# shellcheck disable=SC2034
YQ_SHA_windows_368="6292e14b0c199f2bd33e18a8bfe67f100084837163e1e2bc4934bcd7990a5087"
# shellcheck disable=SC2034
YQ_SHA_windows_amd64="987d31d3a9b75f9cb0f202173aab033d333d2406ba2caa7dba9d16a5204c2167"

YQ_SHA_DEFAULT_NAME="YQ_SHA_${YQ_PLATFORM}_${YQ_ARCH}"
eval YQ_SHA_DEFAULT="\$${YQ_SHA_DEFAULT_NAME}"
YQ_SHA="${YQ_SHA:-"${YQ_SHA_DEFAULT}"}"

RED='\033[0;31m'
NOC='\033[0m'

get_sha_256() {
if [ ! -f "${1}" ]; then
res=''
elif command -v sha256sum >/dev/null; then
res=$(sha256sum "$1")
elif command -v shasum >/dev/null; then
res=$(shasum -a 256 "$1")
else
res=''
fi

echo "$res" | cut -d ' ' -f 1
}

# shellcheck source=scripts/lib/http.sh
. "${SCRIPT_DIR}/lib/http.sh"

if [ -n "${SKIP_YQ_INSTALL+x}" ] && [ "${SKIP_YQ_INSTALL}" = "true" ]; then
echo "Skipping yq installation."
exit 0
fi

YQ_SHA256="$(get_sha_256 "${YQ_PATH}")"

if [ "${YQ_SHA256}" != "${YQ_SHA}" ] || [ "${YQ_SHA256}" = "" ]; then
echo "Installing/Upgrading yq dependency..."

if ! download "${YQ_URL}" >/tmp/yq; then
printf "${RED}%s${NOC}\n" "Can't download yq ..."
exit 1
fi

YQ_SHA256="$(get_sha_256 /tmp/yq)"
if [ "${YQ_SHA256}" = "${YQ_SHA}" ] || [ "${YQ_SHA256}" = "" ]; then
chmod +x /tmp/yq
mv /tmp/yq "${YQ_PATH}/yq${YQ_SUFFIX}"
else
printf "${RED}%s${NOC}\n" "Checksum mismatch : expected ${YQ_SHA} but was ${YQ_SHA256}"
if [ "${YQ_VERSION}" != "${YQ_DEFAULT_VERSION}" ]; then
printf "${RED}%s${NOC}\n" "Forgot to set YQ_SHA?"
fi
echo "Ignoring ..."
fi
rm -f /tmp/yq
fi
26 changes: 26 additions & 0 deletions scripts/lib/file.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env sh

set -eu

# shellcheck source=scripts/lib/file/local.sh
. "${SCRIPT_DIR}/lib/file/local.sh"

# shellcheck source=scripts/lib/file/custom.sh
. "${SCRIPT_DIR}/lib/file/custom.sh"

_file_get_protocol() {
case "$1" in
*://*)
echo "custom"
;;
*)
echo "local"
;;
esac
}

_file_get() {
file_type=$(_file_get_protocol "${1}")

_file_"${file_type}"_get "$@"
}
6 changes: 6 additions & 0 deletions scripts/lib/file/custom.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env sh

_file_custom_get() {
helm template "${SCRIPT_DIR}/lib/file/helm-values-getter" -f "${1}" |
sed -E -e "s/^# Source: .+$//" -e "s/^---$//"
}
3 changes: 3 additions & 0 deletions scripts/lib/file/helm-values-getter/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
apiVersion: v2
name: helm-values-getter
version: 1.0.0
1 change: 1 addition & 0 deletions scripts/lib/file/helm-values-getter/templates/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{- .Values | toYaml -}}
7 changes: 7 additions & 0 deletions scripts/lib/file/local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env sh

set -eu

_file_local_get() {
cat "${1}" 2>/dev/null
}
148 changes: 148 additions & 0 deletions scripts/lib/file_uri_substitution.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,151 @@ file_uri_subst() {

echo "${file_uri}" | sed 's/{{/${/g' | sed 's/}}/}/g'
}

unset_subst_args() {
unset namespace chart release
}

export_subst_args() {
# shellcheck disable=SC2034
export namespace="${HELM_NAMESPACE:-unknown}"
# shellcheck disable=SC2034
export chart="CHART-NAME"
# shellcheck disable=SC2034
export release="RELEASE-NAME"
# shellcheck disable=SC2086
_get_subst_args_value ${1}

# Refine chart value
if [ -d "${chart}" ]; then
chart="$(realpath "${chart}")"
fi
chart="$(basename "${chart}")"
# Remove Semver
chart="$(echo "${chart}" | sed -E 's/(.+)-[0-9]+\.[0-9]+\.[0-9]+(-.+)?/\1/')"
# Remove ext
chart="${chart%%.*}"

log_info "[substitution] Args namespace=${namespace}, chart=${chart}, release=${release}"
}

_get_subst_args_value() {
args=""

# Remove all flags, and put all args into var
i=1
while [ "$i" -le "$#" ]; do
eval "arg=\${$i}"
# shellcheck disable=SC2154
is_flag="$(_is_helm_flag "${arg}")"

if [ "${is_flag}" -gt 0 ]; then
i=$((i + is_flag))
else
args="${args} ${arg}"
i=$((i + 1))
fi
done

log_info "[substitution] analyzing arguments $args"
# shellcheck disable=SC2086
set -- $args

while [ $# -gt 0 ]; do
case "${1:-}" in
lint)
return
;;
template)
if [ $# -ge 3 ]; then
release="${2}"
chart="${3}"
else
chart="${2}"
fi
return
;;
install | upgrade)
release="${2}"
chart="${3}"
return
;;
esac
shift
done
}

_is_helm_flag() {
case "${1:-}" in
# Global Flags :: Key, Value
--repository-config | --repository-cache | --registry-config | -n | --namespace | \
--kubeconfig | --kube-token | --kube-context | --kube-as-user | --kube-as-group | \
--kube-apiserver)
echo 2
;;
# Global Flags :: Key
-h | --help | --debug)
echo 1
;;
# Value Options Flags https://github.com/helm/helm/blob/master/cmd/helm/flags.go#L41
-f | --values | --set | --set-string | --set-file)
echo 2
;;
# ChartPathOptionsFlags https://github.com/helm/helm/blob/master/cmd/helm/flags.go#L48
--version | --keyring | --repo | --username | --password | --cert-file | --key-file | --ca-file)
echo 2
;;
--verify | --insecure-skip-tls-verify)
echo 1
;;
# https://github.com/helm/helm/blob/master/cmd/helm/flags.go#L63
-o | --output | --post-renderer)
echo 2
;;
# Lint flags
--strict | --with-subcharts)
echo 1
;;
# Install Flags
--create-namespace | --dry-run | --no-hooks | --replace | --wait | --devel | \
--dependency-update | --disable-openapi-validation | --atomic | --skip-crds | \
--render-subchart-notes)
echo 1
;;
--timeout | --description)
echo 2
;;
-g | --generate-name)
log_error " Unable to proceed repeatable configuration with a generated name"
return 2
;;
--name-template)
log_error " name-template flag is not supported"
return 2
;;
# Template Flags
-s | --show-only | --output-dir | --api-versions | --release-name)
echo 2
;;
--validate | --include-crds | --is-upgrade)
echo 1
;;
# Upgrade Flags
--history-max)
# Already existing
# --timeout | --description
echo 2
;;
-i | --install | --recreate-pods | --force | --reset-values | \
--reuse-values | --cleanup-on-fail)
# Already existing
# --create-namespace | --devel | --dry-run | --no-hooks |
# --disable-openapi-validation | --skip-crds |
# --wait | --atomic | --render-subchart-notes
echo 1
;;
*)
echo 0
;;
esac
}
Loading

0 comments on commit 9e8de56

Please sign in to comment.