6597059a15
security-catalog 프로젝트에서 자체 빌드 이미지 3종을 실제로 로컬 빌드·게이트 검증하는 과정에서 발견한 문제들: - extract-helm-images.sh 가 `image:` 필드만 잡고 `imageName:`(CNPG Cluster CRD 관례) 은 놓쳐, cnpg-cluster 차트의 이미지가 SBOM·스캔·게이트 어디에도 안 나타났다. - patch-catalog-tag.py 의 split 포맷 패처가 registry 필드가 따로 없고 repository 에 registry+repo 를 합쳐 쓰는 차트(cloudnative-pg 오퍼레이터, 업스트림 템플릿이 image.registry 를 아예 참조하지 않음)에서 tag 만 조용히 갱신하고 repository 는 그대로 남겨 깨진 참조를 만들 수 있었다. - CoverageProbe(센티널 패키지 주입 재스캔으로 "0건"과 "측정 안 됨"을 구분)가 이식되지 않아, 전 심각도 0건인 자체 빌드 이미지가 실제로는 깨끗한데도 게이트가 "데이터 커버리지 이상"으로 오탐 처리했다 — security-catalog 의 scan-sbom.sh 를 이식해 해소. cve-gate.py 는 이미 이 키를 읽도록 구현돼 있어 소비 쪽 변경은 없다. rpm(SUSE)·deb(Debian)·apk(Alpine) 세 센티널 경로와 병렬 스캔 회귀를 로컬에서 확인했고, 이식 후 cloudnative-pg·cnpg-postgresql 게이트가 실제로 FAIL→PASS 로 바뀌는 것도 확인했다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
91 lines
3.7 KiB
Bash
Executable File
91 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# extract-helm-images.sh
|
|
# dip-catalog 정적 Helm 카탈로그에서 컨테이너 이미지 인벤토리를 추출한다.
|
|
#
|
|
# 방법 (100% deterministic, LLM 미사용):
|
|
# 각 차트 버전 디렉토리를 `helm template` 로 렌더 → 렌더된 매니페스트에서
|
|
# `image:` 필드를 추출 → 정규화/중복 제거.
|
|
#
|
|
# custom-values.yaml 이 있으면 적용하여 "실제 배포되는(effective) 이미지"를
|
|
# 뽑는다. 없으면 차트 기본값으로 렌더한다.
|
|
#
|
|
# 사용:
|
|
# bash doc/scripts/extract-helm-images.sh [HELM_ROOT] [OUT_DIR]
|
|
# HELM_ROOT 기본값: <repo>/manifests/helm
|
|
# OUT_DIR 기본값: 현재 디렉토리
|
|
#
|
|
# 산출물:
|
|
# images_final.tsv chart<TAB>version<TAB>image (정렬/중복제거)
|
|
# render_status.tsv chart<TAB>version<TAB>mode<TAB>status
|
|
#
|
|
# 요구사항: helm v3, bash, awk, sed, grep
|
|
# =============================================================================
|
|
set -uo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
HELM_ROOT="${1:-$(cd "$SCRIPT_DIR/../../manifests/helm" && pwd)}"
|
|
OUT_DIR="${2:-$(pwd)}"
|
|
|
|
# bitnamilegacy 이미지가 있는 차트는 Bitnami common 의 insecureImages 가드에
|
|
# 걸리므로 렌더 시 허용 플래그가 필요하다.
|
|
KUBE_VERSION="${KUBE_VERSION:-1.31.0}"
|
|
COMMON_SET=(--set global.security.allowInsecureImages=true)
|
|
|
|
RAW="$OUT_DIR/images_raw.tsv"
|
|
FINAL="$OUT_DIR/images_final.tsv"
|
|
STATUS="$OUT_DIR/render_status.tsv"
|
|
: > "$RAW"; : > "$STATUS"
|
|
|
|
cd "$HELM_ROOT"
|
|
|
|
extract_images() { # stdin: 렌더된 yaml → stdout: 이미지 문자열
|
|
# `image:` 뿐 아니라 `imageName:` 도 잡는다 — CNPG Cluster CRD(cnpg-cluster 차트의
|
|
# postgresql.imageName)처럼 단일 문자열 필드로 이미지를 표기하는 관례가 있다
|
|
# (patch-catalog-tag.py 의 TAG_STYLE=imageName 과 같은 표기). 이걸 놓치면 그 이미지가
|
|
# SBOM·스캔·게이트 어디에도 나타나지 않고 조용히 빠진다(실측: cnpg-cluster).
|
|
grep -ioE '^[[:space:]]*(- )?image(Name)?:[[:space:]]*"?[^"[:space:]]+' \
|
|
| sed -E 's/.*image(Name)?:[[:space:]]*"?//' \
|
|
| grep -vE '^$'
|
|
}
|
|
|
|
for chart in */; do
|
|
chart="${chart%/}"
|
|
for vdir in "$chart"/*/; do
|
|
[ -f "${vdir}Chart.yaml" ] || continue
|
|
version="$(basename "$vdir")"
|
|
|
|
args=(template t "$vdir" --kube-version "$KUBE_VERSION" "${COMMON_SET[@]}")
|
|
mode="default"
|
|
if [ -f "${vdir}custom-values.yaml" ]; then
|
|
args+=(-f "${vdir}custom-values.yaml")
|
|
mode="effective"
|
|
fi
|
|
|
|
if out="$(helm "${args[@]}" 2>/tmp/_helmerr)"; then
|
|
echo -e "${chart}\t${version}\t${mode}\tOK" >> "$STATUS"
|
|
elif [ "$mode" = "effective" ] && out="$(helm template t "$vdir" --kube-version "$KUBE_VERSION" "${COMMON_SET[@]}" 2>/tmp/_helmerr)"; then
|
|
echo -e "${chart}\t${version}\tdefault-fallback\tOK" >> "$STATUS"
|
|
else
|
|
echo -e "${chart}\t${version}\t${mode}\tFAIL: $(head -1 /tmp/_helmerr | cut -c1-120)" >> "$STATUS"
|
|
out=""
|
|
fi
|
|
|
|
[ -n "$out" ] || continue
|
|
while read -r img; do
|
|
[ -z "$img" ] && continue
|
|
echo -e "${chart}\t${version}\t${img}" >> "$RAW"
|
|
done < <(printf '%s\n' "$out" | extract_images)
|
|
done
|
|
done
|
|
|
|
# 정규화(따옴표 제거) + 정렬 + 중복 제거
|
|
awk -F'\t' '{gsub(/^['"'"'"]+|['"'"'"]+$/,"",$3); if($3!="") print $1"\t"$2"\t"$3}' "$RAW" \
|
|
| sort -u > "$FINAL"
|
|
|
|
echo "== 렌더 상태 =="
|
|
awk -F'\t' '{s=$4; sub(/FAIL.*/,"FAIL",s); print s}' "$STATUS" | sort | uniq -c
|
|
echo "== 커버 차트 : $(cut -f1 "$FINAL" | sort -u | wc -l | tr -d ' ') =="
|
|
echo "== 고유 이미지: $(cut -f3 "$FINAL" | sort -u | wc -l | tr -d ' ') =="
|
|
echo "== 산출물 : $FINAL =="
|