mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-03 20:57:05 +02:00
* feat: add `inherits:` for sub-helmfile config inheritance
Add an opt-in `inherits:` field to `helmfiles:` entries so a sub-helmfile
can inherit specific configuration categories from its parent:
helmfiles:
- path: myapp.yaml
inherits: [repositories, environments]
Allowed values: repositories, helmDefaults, commonLabels, apiVersions,
kubeVersion, templates, environments. Child values win; parent fills gaps
(consistent with `bases:`). This directly fixes #1495, where a repository
declared in the parent was unavailable to sub-helmfiles, producing a
confusing "repo not found" error.
Implementation notes:
- The 6 pure fields (repositories, helmDefaults, commonLabels, apiVersions,
kubeVersion, templates) are merged post-load via MergeInherited; verified
all are consumed post-load (ExecuteTemplates/converge), never at parse.
- environments is injected pre-load as ctxEnv, because RenderedValues is
baked at load time; the parent's resolved values become the base and the
child's own environments: block overrides per key.
- helmDefaults uses a *HelmSpec pointer (value type is non-comparable) with
a no-override mergo merge, so a child that omits helmDefaults inherits the
parent's fully.
- A footgun warning (WarnUninheritedRepos) suggests
`inherits: [repositories]` when a release references a repo the parent
declares but the child lacks.
- Unknown inherits keys are rejected at parse time with the allowed set.
Inheritance is opt-in and fully backward compatible: empty (the default)
preserves the historical independent-sub-helmfile behavior.
Fixes #1495
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address review — deep-copy inherited config and fix bases: doc link
- BuildInheritedConfig now deep-copies the pure fields via a YAML round-trip
(Env via environment.DeepCopy) so the returned config never aliases the
parent state's slices/maps, matching its doc comment. Now returns an error
to surface round-trip failures; the call site in processNestedHelmfiles is
updated. Added TestBuildInheritedConfig_PureFieldsAreDeepCopied to lock
in the no-aliasing guarantee.
- Fix the broken `bases:` anchor (#) in shared-configuration-across-teams.md
to point to writing-helmfile.md#layering-state-files.
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address review — reject inherits without path and document helmDefaults caveat
Signed-off-by: yxxhero <aiopsclub@163.com>
* fix: address review — make AllowedInherits immutable and clarify effective-repo wording
Signed-off-by: yxxhero <aiopsclub@163.com>
---------
Signed-off-by: yxxhero <aiopsclub@163.com>
158 lines
6.5 KiB
Bash
Executable File
158 lines
6.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# vim: set tabstop=4 shiftwidth=4
|
|
|
|
set -e
|
|
set -o pipefail
|
|
|
|
# IMPORTS -----------------------------------------------------------------------------------------------------------
|
|
|
|
# determine working directory to use to relative paths irrespective of starting directory
|
|
dir="${BASH_SOURCE%/*}"
|
|
if [[ ! -d "${dir}" ]]; then dir="${PWD}"; fi
|
|
|
|
. "${dir}/lib/output.sh"
|
|
. "${dir}/lib/ensure.sh"
|
|
. "${dir}/lib/version.sh"
|
|
|
|
|
|
# GLOBALS -----------------------------------------------------------------------------------------------------------
|
|
|
|
test_ns="helmfile-tests"
|
|
helmfile="./helmfile ${EXTRA_HELMFILE_FLAGS} --namespace=${test_ns}"
|
|
helm="helm --kube-context=minikube"
|
|
kubectl="kubectl --context=minikube --namespace=${test_ns}"
|
|
helm_dir="${PWD}/${dir}/.helm"
|
|
cases_dir="${dir}/test-cases"
|
|
export HELM_DATA_HOME="${helm_dir}/data"
|
|
export HELM_HOME="${HELM_DATA_HOME}"
|
|
export HELM_PLUGINS="${HELM_DATA_HOME}/plugins"
|
|
export HELM_CONFIG_HOME="${helm_dir}/config"
|
|
HELM_DIFF_VERSION="${HELM_DIFF_VERSION:-3.15.10}"
|
|
HELM_GIT_VERSION="${HELM_GIT_VERSION:-1.4.1}"
|
|
HELM_SECRETS_VERSION="${HELM_SECRETS_VERSION:-4.7.4}"
|
|
export GNUPGHOME="${PWD}/${dir}/.gnupg"
|
|
export SOPS_PGP_FP="B2D6D7BBEC03B2E66571C8C00AD18E16CFDEF700"
|
|
|
|
# FUNCTIONS ----------------------------------------------------------------------------------------------------------
|
|
|
|
function wait_deploy_ready() {
|
|
${kubectl} rollout status deployment ${1} --timeout=300s || {
|
|
info "Deployment ${1} rollout timed out, checking pod status:"
|
|
${kubectl} get pods -o wide --namespace=${test_ns} 2>/dev/null || true
|
|
${kubectl} describe deployment ${1} --namespace=${test_ns} 2>/dev/null | tail -20 || true
|
|
fail "Deployment ${1} failed to become ready within 300s"
|
|
}
|
|
while [ "$(${kubectl} get deploy ${1} -o=jsonpath='{.status.readyReplicas}')" == "0" ]; do
|
|
info "Waiting for deployment ${1} to be ready"
|
|
sleep 1
|
|
done
|
|
}
|
|
function retry() {
|
|
local -r max=${1}
|
|
local -r command=${2}
|
|
n=0
|
|
retry_result=0
|
|
until [ ${n} -ge ${max} ]; do
|
|
info "Executing: ${command} (attempt $((n+1)))"
|
|
${command} && break # substitute your command here
|
|
retry_result=$?
|
|
n=$[$n+1]
|
|
# approximated binary exponential backoff to reduce flakiness
|
|
sleep $((n ** 2))
|
|
done
|
|
}
|
|
|
|
function cleanup() {
|
|
set +e
|
|
info "Deleting ${helm_dir}"
|
|
rm -rf ${helm_dir} # remove helm data so reinstalling plugins does not fail
|
|
info "Deleting minikube namespace ${test_ns}"
|
|
$kubectl delete namespace ${test_ns} # remove namespace whenever we exit this script
|
|
}
|
|
|
|
# SETUP --------------------------------------------------------------------------------------------------------------
|
|
|
|
set -e
|
|
trap cleanup EXIT
|
|
info "Using namespace: ${test_ns}"
|
|
info "Using Helm version:" $(${helm} version --short | grep -o 'v[0-9.]\+')
|
|
|
|
# Detect Helm 4 and add --verify=false flag if needed (Helm 4 requires this for plugins without signatures)
|
|
PLUGIN_INSTALL_FLAGS=""
|
|
if [ "${HELMFILE_HELM4}" = "1" ]; then
|
|
info "Detected Helm 4, adding --verify=false to plugin installations"
|
|
PLUGIN_INSTALL_FLAGS="--verify=false"
|
|
# Set HELM_BIN for helm-git plugin compatibility with Helm 4
|
|
export HELM_BIN=$(which helm)
|
|
info "Set HELM_BIN=${HELM_BIN} for Helm 4 plugin compatibility"
|
|
fi
|
|
|
|
${helm} plugin ls | grep "^diff" || ${helm} plugin install https://github.com/databus23/helm-diff --version v${HELM_DIFF_VERSION} ${PLUGIN_INSTALL_FLAGS}
|
|
${helm} plugin ls | grep "^helm-git" || ${helm} plugin install https://github.com/aslafy-z/helm-git --version v${HELM_GIT_VERSION} ${PLUGIN_INSTALL_FLAGS}
|
|
info "Using Kustomize version: $(kustomize version --short | grep -o 'v[0-9.]\+')"
|
|
${kubectl} get namespace ${test_ns} &> /dev/null && warn "Namespace ${test_ns} exists, from a previous test run?"
|
|
${kubectl} create namespace ${test_ns} || fail "Could not create namespace ${test_ns}"
|
|
|
|
|
|
# TEST CASES----------------------------------------------------------------------------------------------------------
|
|
|
|
. ${dir}/test-cases/issue-2502-race-condition-local-chart.sh
|
|
. ${dir}/test-cases/chart-deps-condition.sh
|
|
. ${dir}/test-cases/fetch-forl-local-chart.sh
|
|
. ${dir}/test-cases/fetch-write-output.sh
|
|
. ${dir}/test-cases/suppress-output-line-regex.sh
|
|
. ${dir}/test-cases/chartify-jsonPatches-and-strategicMergePatches.sh
|
|
. ${dir}/test-cases/include-template-func.sh
|
|
. ${dir}/test-cases/happypath.sh
|
|
. ${dir}/test-cases/chartify-with-non-chart-dir.sh
|
|
. ${dir}/test-cases/diff-args.sh
|
|
. ${dir}/test-cases/helmfile-double-fetch.sh
|
|
. ${dir}/test-cases/skip-diff-output.sh
|
|
. ${dir}/test-cases/v1-subhelmfile-multi-bases-with-array-values.sh
|
|
. ${dir}/test-cases/inherits-subhelmfile.sh
|
|
. ${dir}/test-cases/kustomized-fetch.sh
|
|
. ${dir}/test-cases/issue-2503-kustomize-fetch.sh
|
|
. ${dir}/test-cases/regression.sh
|
|
. ${dir}/test-cases/secretssops.sh
|
|
. ${dir}/test-cases/yaml-overwrite.sh
|
|
. ${dir}/test-cases/chart-needs.sh
|
|
. ${dir}/test-cases/postrender.sh
|
|
. ${dir}/test-cases/postrender-defaults-args.sh
|
|
. ${dir}/test-cases/issue-2515.sh
|
|
. ${dir}/test-cases/chartify.sh
|
|
. ${dir}/test-cases/deps-mr-1011.sh
|
|
. ${dir}/test-cases/deps-kustomization-i-1402.sh
|
|
. ${dir}/test-cases/hcl-secrets.sh
|
|
. ${dir}/test-cases/issue-1749.sh
|
|
. ${dir}/test-cases/issue-1893.sh
|
|
. ${dir}/test-cases/state-values-set-cli-args-in-environments.sh
|
|
. ${dir}/test-cases/issue-2281-array-merge.sh
|
|
. ${dir}/test-cases/issue-2353-layer-array-replace.sh
|
|
. ${dir}/test-cases/issue-2451-nested-helmfile-array-replace.sh
|
|
. ${dir}/test-cases/issue-2247.sh
|
|
. ${dir}/test-cases/issue-2097.sh
|
|
. ${dir}/test-cases/issue-2291.sh
|
|
. ${dir}/test-cases/oci-parallel-pull.sh
|
|
. ${dir}/test-cases/issue-2297-local-chart-transformers.sh
|
|
. ${dir}/test-cases/issue-2309-kube-context-template.sh
|
|
. ${dir}/test-cases/issue-2355.sh
|
|
. ${dir}/test-cases/issue-2103.sh
|
|
. ${dir}/test-cases/unittest.sh
|
|
. ${dir}/test-cases/issue-2409-sequential-kubecontext.sh
|
|
. ${dir}/test-cases/issue-2269.sh
|
|
. ${dir}/test-cases/issue-2418.sh
|
|
. ${dir}/test-cases/issue-2424-sequential-values-paths.sh
|
|
. ${dir}/test-cases/issue-2431.sh
|
|
. ${dir}/test-cases/issue-2544.sh
|
|
. ${dir}/test-cases/issue-2596-local-deps-multiple-files.sh
|
|
. ${dir}/test-cases/issue-1880-transformers-with-file-deps.sh
|
|
. ${dir}/test-cases/issue-821-adhoc-dep-go-getter.sh
|
|
. ${dir}/test-cases/issue-2599-default-inherit.sh
|
|
. ${dir}/test-cases/issue-1172-selector-required-env.sh
|
|
. ${dir}/test-cases/kubedog-tracking.sh
|
|
. ${dir}/test-cases/lookup.sh
|
|
|
|
# ALL DONE -----------------------------------------------------------------------------------------------------------
|
|
|
|
all_tests_passed
|