From 5b5e5bbf9380c0f33dee496788ba4a7edc98c215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Mon, 22 Nov 2021 19:35:02 +0100 Subject: [PATCH] Add variable expansion --- CHANGELOG.md | 6 ++++++ scripts/lib/expand_vars_strict.sh | 21 +++++++++++++++++++++ scripts/lib/file/http.sh | 11 ++++++++++- scripts/run.sh | 3 +++ tests/unit/template.bats | 27 +++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 scripts/lib/expand_vars_strict.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e68ce65..f17bb9d85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Allow override sops version on installation +## [Unreleased] + +### Added +- Add environment variable expansion for value files like `secrets://https://${GITHUB_TOKEN}@raw.githubusercontent.com/org/repo/ref/pathtofile.yml`. + This feature is disabled by default and can be enabled by set the env var `HELM_SECRETS_URL_VARIABLE_EXPANSION=true` + ## [3.10.0] - 2021-11-05 ### Added diff --git a/scripts/lib/expand_vars_strict.sh b/scripts/lib/expand_vars_strict.sh new file mode 100644 index 000000000..e654e09a7 --- /dev/null +++ b/scripts/lib/expand_vars_strict.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env sh + +set -euf + +# https://stackoverflow.com/a/40167919 +expand_vars_strict() { + _x4=$(printf '\x4') + # the `||` clause ensures that the last line is read even if it doesn't end with \n + while IFS= read -r line || [ -n "${line}" ]; do + # Escape ALL chars. that could trigger an expansion.. + lineEscaped=$( + printf %s "$line" | + tr '`([$' '\1\2\3\4' | + # ... then selectively reenable ${ references + sed -e "s/$_x4{/\${/g" | + # Finally, escape embedded double quotes to preserve them. + sed -e 's/"/\\\"/g' + ) + eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([$' + done +} diff --git a/scripts/lib/file/http.sh b/scripts/lib/file/http.sh index 89af9478c..cac9a6ecc 100644 --- a/scripts/lib/file/http.sh +++ b/scripts/lib/file/http.sh @@ -2,13 +2,22 @@ set -euf +URL_VARIABLE_EXPANSION="${HELM_SECRETS_URL_VARIABLE_EXPANSION:-false}" + _file_http_exists() { _file_http_get "$@" >/dev/null } _file_http_get() { _tmp_file=$(_mktemp) - if ! download "${1}" >"${_tmp_file}"; then + + if [ "${URL_VARIABLE_EXPANSION}" = "true" ]; then + _url="$(printf '%s' "${1}" | expand_vars_strict)" + else + _url="${1}" + fi + + if ! download "${_url}" >"${_tmp_file}"; then exit 1 fi diff --git a/scripts/run.sh b/scripts/run.sh index f0b01db73..307bef3bf 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -16,6 +16,9 @@ SCRIPT_DIR="$(dirname "$0")" # shellcheck source=scripts/lib/common.sh . "${SCRIPT_DIR}/lib/common.sh" +# shellcheck source=scripts/lib/expand_vars_strict.sh +. "${SCRIPT_DIR}/lib/expand_vars_strict.sh" + # shellcheck source=scripts/lib/file.sh . "${SCRIPT_DIR}/lib/file.sh" diff --git a/tests/unit/template.bats b/tests/unit/template.bats index 6ee8a5860..3cfa495eb 100755 --- a/tests/unit/template.bats +++ b/tests/unit/template.bats @@ -341,6 +341,33 @@ load '../bats/extensions/bats-file/load' assert_output --partial "port: 81" } +@test "template: helm template w/ chart + secrets.yaml + secrets://http:// + HELM_SECRETS_URL_VARIABLE_EXPANSION=true" { + if on_windows || ! is_driver "sops"; then + # For vault its pretty hard to have a committed files with temporary seed of this test run + skip + fi + FILE="secrets://https://raw.githubusercontent.com/\${GH_OWNER}/\${GH_REPO}/main/tests/assets/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run env HELM_SECRETS_URL_VARIABLE_EXPANSION=true GH_OWNER=jkroepke GH_REPO=helm-secrets helm template "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "port: 81" +} + +@test "template: helm template w/ chart + secrets.yaml + secrets://http:// + HELM_SECRETS_URL_VARIABLE_EXPANSION=false" { + if on_windows || ! is_driver "sops"; then + # For vault its pretty hard to have a committed files with temporary seed of this test run + skip + fi + FILE="secrets://https://raw.githubusercontent.com/\${GH_OWNER}/\${GH_REPO}/main/tests/assets/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run env HELM_SECRETS_URL_VARIABLE_EXPANSION=false helm template "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_failure +} + @test "template: helm template w/ chart + secrets.yaml + secrets://http://example.com/404.yaml" { if on_windows || ! is_driver "sops"; then # For vault its pretty hard to have a committed files with temporary seed of this test run