Files
helmfile/test/integration/run.sh
T
yxxhero 6e21671228 feat: kubedog integration with unified resource handling (#2383)
* feat: add kubedog-based resource tracking integration

Add kubedog tracking as an alternative to Helm's --wait flag with:
- Real-time deployment progress tracking
- Container log streaming
- Fine-grained resource filtering (trackKinds/skipKinds/trackResources)

Features:
- New pkg/resource package for unified manifest parsing and filtering
- New pkg/kubedog package wrapping kubedog library
- CLI flags: --track-mode, --track-timeout, --track-logs
- Helmfile YAML support for trackMode, trackTimeout, trackLogs, trackKinds, skipKinds, trackResources
- Case-insensitive kind matching for filtering
- Multi-context support with proper kubeconfig/kubeContext handling

Tracking supports: Deployment, StatefulSet, DaemonSet, Job

Resource filtering priority (highest to lowest):
1. trackResources - explicit resource whitelist
2. skipKinds - blacklist specific kinds
3. trackKinds - whitelist specific kinds

Integration:
- Disable Helm --wait when using kubedog tracking
- Track after successful Helm sync/apply
- Respect release.Namespace as fallback for resources without namespace
- Use getKubeContext() for correct cluster targeting

Tests:
- Unit tests for resource filtering and kubedog options
- Integration test with httpbin chart
- E2E snapshot tests for YAML serialization
- Documentation in docs/advanced-features.md

Signed-off-by: yxxhero <aiopsclub@163.com>

* fix: address PR #2383 review comments (round 4)

1. resource/filter.go: Skip empty whitelist entries in matchWhitelist
   - At least one field (kind/name/namespace) must be specified
   - Prevents matching all resources with empty TrackResources entries

2. config/apply.go: Add ValidateConfig for track-mode validation
   - Validate --track-mode must be 'helm' or 'kubedog'
   - Reject invalid values like --track-mode foo

3. config/sync.go: Add ValidateConfig for track-mode validation
   - Same validation as apply command
   - Ensures consistent behavior across commands

Signed-off-by: yxxhero <aiopsclub@163.com>

---------

Signed-off-by: yxxhero <aiopsclub@163.com>
2026-03-02 17:15:12 +08:00

143 lines
5.8 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.1}"
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/fetch-forl-local-chart.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/kustomized-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/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-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/kubedog-tracking.sh
# ALL DONE -----------------------------------------------------------------------------------------------------------
all_tests_passed