Skip to content

Commit 68797c8

Browse files
ci(manifests): validates kustomize manifests (#890)
To ensure that our kustomize manifests are always valid, this PR brings a validation script and gh action to ensure that. > [!IMPORTANT] > This only checks if kustomize can process YAMLs, it does not mean it can be successfully applied to the cluster. In addition, detected failures have been addressed by adding "placeholder" files that are replaced on the fly in certain targets. Signed-off-by: Bartosz Majsak <[email protected]> Co-authored-by: Filippe Spolti <[email protected]>
1 parent 85ec0f4 commit 68797c8

File tree

4 files changed

+116
-2
lines changed

4 files changed

+116
-2
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Validation
2+
3+
on:
4+
pull_request:
5+
push:
6+
7+
jobs:
8+
validate-manifests:
9+
name: Validate Kustomize manifests
10+
timeout-minutes: 10
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}-validate-manifests
13+
cancel-in-progress: true
14+
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v5
19+
20+
- name: Install kustomize
21+
run: |
22+
set -euo pipefail
23+
curl -fsSL "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s -- 5.7.1
24+
sudo mv kustomize /usr/local/bin/
25+
26+
- name: Validate Kustomize manifests
27+
run: |
28+
# Exclude development overlays and dev-image-config overlays
29+
# Certain files are .gitignored and will cause the validation to fail
30+
set -euo pipefail
31+
./hack/validate-manifests.sh \
32+
--ignore config/overlays/development \
33+
--ignore config/overlays/dev-image-config \
34+
--ignore test/overlays/istio

hack/validate-manifests.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
bold='\033[1m'
6+
normal='\033[0m'
7+
underline='\033[4m'
8+
9+
validate_kustomization() {
10+
local kustomization_file="$1"
11+
local project_root="${2:-$(git rev-parse --show-toplevel)}"
12+
13+
local dir
14+
dir=$(dirname "$kustomization_file")
15+
local relative_path=${kustomization_file#"$project_root/"}
16+
local message="${bold}Validating${normal} ${underline}$relative_path${normal}"
17+
18+
echo -n -e "${message}"
19+
if output=$(kustomize build --load-restrictor LoadRestrictionsNone --stack-trace "$dir" 2>&1); then
20+
echo -e "\r✅ ${message}"
21+
return 0
22+
else
23+
echo -e "\r❌ ${message}"
24+
echo "$output"
25+
return 1
26+
fi
27+
}
28+
29+
validate_all() {
30+
local project_root="$1"; shift
31+
local ignore_paths=("$@")
32+
local exit_code=0
33+
34+
while IFS= read -r -d '' kustomization_file; do
35+
local skip=false
36+
for ignore in "${ignore_paths[@]}"; do
37+
if [[ "$kustomization_file" == "$project_root/$ignore"* ]]; then
38+
skip=true
39+
break
40+
fi
41+
done
42+
43+
if [[ $skip == true ]]; then
44+
continue
45+
fi
46+
47+
if ! validate_kustomization "$kustomization_file" "$project_root"; then
48+
exit_code=1
49+
fi
50+
done < <(find "$project_root" -name "kustomization.yaml" -type f -print0)
51+
52+
return $exit_code
53+
}
54+
55+
# When script is not sourced, but directly invoked
56+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
57+
PROJECT_ROOT=$(git rev-parse --show-toplevel)
58+
59+
ignore_paths=()
60+
while [[ $# -gt 0 ]]; do
61+
case "$1" in
62+
--ignore)
63+
shift
64+
[[ $# -gt 0 ]] || { echo "Error: --ignore requires a path"; exit 1; }
65+
ignore_paths+=("$1")
66+
;;
67+
*)
68+
echo "Unknown argument: $1"
69+
exit 1
70+
;;
71+
esac
72+
shift
73+
done
74+
75+
validate_all "$PROJECT_ROOT" "${ignore_paths[@]}"
76+
exit $?
77+
fi

test/overlays/istio/kustomization.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
22
kind: Kustomization
33

44
resources:
5-
- generated-manifest.yaml
5+
- generated-manifest.yaml # ./test/scripts/gh-actions/setup-deps.sh updates manifests on the fly
66

77
patches:
88
- path: istio_ingressgateway_patch.yaml

test/scripts/gh-actions/setup-deps.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ if [[ $NETWORK_LAYER == "istio-ingress" || $NETWORK_LAYER == "istio-gatewayapi"
7676
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=${ISTIO_VERSION} sh -
7777
cd istio-${ISTIO_VERSION}
7878
export PATH=$PWD/bin:$PATH
79-
istioctl manifest generate --set meshConfig.accessLogFile=/dev/stdout >${SCRIPT_DIR}/../../overlays/istio/generated-manifest.yaml
79+
{
80+
printf "## GENERATED - DO NOT EDIT\n## istioctl manifest generate --set meshConfig.accessLogFile=/dev/stdout > test/overlays/istio/generated-manifest.yaml\n";
81+
istioctl manifest generate --set meshConfig.accessLogFile=/dev/stdout;
82+
} > ${SCRIPT_DIR}/../../overlays/istio/generated-manifest.yaml
8083
popd
8184
kubectl create ns istio-system
8285
for i in {1..3}; do kubectl apply -k test/overlays/istio && break || sleep 15; done

0 commit comments

Comments
 (0)