175 lines
3.6 KiB
Bash
Executable File
175 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -Eeuo pipefail
|
|
|
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "${repo_root}"
|
|
|
|
required_tools=(
|
|
bash
|
|
find
|
|
git
|
|
grep
|
|
kubectl
|
|
make
|
|
sed
|
|
)
|
|
|
|
optional_tools=(
|
|
age
|
|
argocd
|
|
conftest
|
|
flux
|
|
gitleaks
|
|
helm
|
|
kubeconform
|
|
shellcheck
|
|
sops
|
|
terraform
|
|
tofu
|
|
trivy
|
|
yamllint
|
|
)
|
|
|
|
activated_tools=()
|
|
missing=0
|
|
|
|
collect_source_files() {
|
|
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
git ls-files --cached --others --exclude-standard -z
|
|
else
|
|
find . \
|
|
\( \
|
|
-type d \
|
|
\( \
|
|
-name .build -o \
|
|
-name .cache -o \
|
|
-name .git -o \
|
|
-name .terraform -o \
|
|
-name .terragrunt-cache -o \
|
|
-name dist -o \
|
|
-name rendered -o \
|
|
-name tmp \
|
|
\) -prune \
|
|
\) -o \
|
|
-type f -print0
|
|
fi
|
|
}
|
|
|
|
source_files=()
|
|
while IFS= read -r -d '' file; do
|
|
file="${file#./}"
|
|
if [[ -f "${file}" ]]; then
|
|
source_files+=("${file}")
|
|
fi
|
|
done < <(collect_source_files)
|
|
|
|
has_chart=0
|
|
iac_file=""
|
|
for file in "${source_files[@]}"; do
|
|
if [[ "${file##*/}" == "Chart.yaml" ]]; then
|
|
has_chart=1
|
|
fi
|
|
|
|
case "${file}" in
|
|
bootstrap/*.tf | bootstrap/*.tf.json | bootstrap/*.tofu | bootstrap/*.tofu.json | \
|
|
infrastructure/*.tf | infrastructure/*.tf.json | infrastructure/*.tofu | \
|
|
infrastructure/*.tofu.json)
|
|
iac_file="${file}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if ((has_chart == 1)); then
|
|
activated_tools+=("helm")
|
|
fi
|
|
|
|
if [[ -n "${iac_file}" ]]; then
|
|
iac_engine=""
|
|
if [[ -f infrastructure/.iac-engine && ! -L infrastructure/.iac-engine ]]; then
|
|
iac_engine_values=()
|
|
while IFS= read -r line; do
|
|
case "${line}" in
|
|
"" | \#*)
|
|
continue
|
|
;;
|
|
esac
|
|
iac_engine_values+=("${line}")
|
|
done < infrastructure/.iac-engine
|
|
|
|
if ((${#iac_engine_values[@]} == 1)); then
|
|
iac_engine="${iac_engine_values[0]}"
|
|
fi
|
|
fi
|
|
|
|
case "${iac_engine}" in
|
|
terraform | tofu)
|
|
activated_tools+=("${iac_engine}")
|
|
;;
|
|
*)
|
|
printf '[missing] infrastructure/.iac-engine must select terraform or tofu because IaC files exist.\n' >&2
|
|
missing=1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
is_activated() {
|
|
local candidate="$1"
|
|
local tool
|
|
|
|
for tool in "${activated_tools[@]}"; do
|
|
if [[ "${candidate}" == "${tool}" ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
printf 'Required tools\n'
|
|
for tool in "${required_tools[@]}"; do
|
|
if command -v "${tool}" >/dev/null 2>&1; then
|
|
printf ' [ok] %-14s %s\n' "${tool}" "$(command -v "${tool}")"
|
|
else
|
|
printf ' [missing] %s\n' "${tool}"
|
|
missing=1
|
|
fi
|
|
done
|
|
|
|
if ((${#activated_tools[@]} > 0)); then
|
|
printf '\nTools required by activated source files\n'
|
|
for tool in "${activated_tools[@]}"; do
|
|
if command -v "${tool}" >/dev/null 2>&1; then
|
|
printf ' [ok] %-14s %s\n' "${tool}" "$(command -v "${tool}")"
|
|
else
|
|
printf ' [missing] %s\n' "${tool}"
|
|
missing=1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
printf '\nOptional tools (required only after the related feature is enabled)\n'
|
|
for tool in "${optional_tools[@]}"; do
|
|
if is_activated "${tool}"; then
|
|
continue
|
|
fi
|
|
|
|
if command -v "${tool}" >/dev/null 2>&1; then
|
|
printf ' [found] %-14s %s\n' "${tool}" "$(command -v "${tool}")"
|
|
else
|
|
printf ' [not set] %s\n' "${tool}"
|
|
fi
|
|
done
|
|
|
|
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
printf '\nRepository: Git work tree detected.\n'
|
|
else
|
|
printf '\nRepository: Git is not initialized yet; run git init when this skeleton becomes a repository.\n'
|
|
fi
|
|
|
|
if ((missing != 0)); then
|
|
printf '\nInstall/configure the missing required items before validation.\n' >&2
|
|
exit 1
|
|
fi
|
|
|
|
printf '\nDoctor check passed.\n'
|