-
Notifications
You must be signed in to change notification settings - Fork 25
ci: image collection and scanning #461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c154249
5bfeeca
90abd36
a30bb79
5ddfa64
c3c02ff
cfe8960
70fa56f
fb67d24
279eb27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,6 +57,52 @@ jobs: | |
| - name: Install go-licenses | ||
| run: go install github.com/google/go-licenses/v2@3e084b0caf710f7bfead967567539214f598c0a2 #v2.0.1 | ||
|
|
||
| - name: Verify preinstalled Helm | ||
| run: | | ||
| set -euo pipefail | ||
| helm version --short | ||
|
|
||
| - name: Run kubara generate | ||
| env: | ||
| KUBARA_PROJECT_NAME: kubara | ||
| KUBARA_PROJECT_STAGE: tst | ||
| KUBARA_DOCKERCONFIG_BASE64: "000000" | ||
| KUBARA_ARGOCD_WIZARD_ACCOUNT_PASSWORD: "000000" | ||
| KUBARA_ARGOCD_HELM_REPO_USERNAME: git | ||
| KUBARA_ARGOCD_HELM_REPO_PASSWORD: "000000" | ||
| KUBARA_ARGOCD_HELM_REPO_URL: "https://kubara.io/kubara.git" | ||
| KUBARA_ARGOCD_GIT_HTTPS_URL: "https://kubara.io/kubara.git" | ||
| KUBARA_ARGOCD_GIT_PAT_OR_PASSWORD: "000000" | ||
| KUBARA_ARGOCD_GIT_USERNAME: git | ||
| KUBARA_DNS_NAME: kubara-tst.stackit.run | ||
| KUBARA_STACKIT_PROJECT_ID: "00000000-0000-0000-0000-000000000000" | ||
| KUBARA_TERRAFORM_PROVIDER: stackit | ||
| KUBARA_CLUSTER_TYPE: hub | ||
| KUBARA_SSO_ORG: Kubara | ||
| KUBARA_SSO_TEAM: Test | ||
| KUBARA_KUBERNETES_TYPE: ske | ||
| KUBARA_KUBERNETES_VERSION: "1.35.0" | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p /tmp/gen | ||
| (cd src && go run main.go --work-dir /tmp/gen init --prep) | ||
| .scripts/kubara-env-update.sh /tmp/gen/.env | ||
| (cd src && go run main.go --work-dir /tmp/gen init) | ||
| .scripts/kubara-config-update.sh /tmp/gen/config.yaml | ||
| (cd src && go run main.go --work-dir /tmp/gen generate) | ||
|
|
||
| - name: Extract images and set goreleaser header | ||
| run: | | ||
| MANAGED=/tmp/gen/managed-service-catalog/helm \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Small path mismatch here: the generated files live under As written the script would exit before GoReleaser, so the header wouldn't be filled. Something like: should fix it. (Not caught by PR CI since release only runs on tag push.) |
||
| OUTPUT_FILE=/tmp/images.txt \ | ||
| "$GITHUB_WORKSPACE"/.scripts/image-version.sh | ||
| { | ||
| echo "IMAGE_LIST<<EOF" | ||
| sed 's/^/- `/' /tmp/images.txt | sed 's/$/ `/' | ||
| echo "EOF" | ||
| } >> "$GITHUB_ENV" | ||
|
|
||
|
|
||
| - name: Run GoReleaser | ||
| if: github.event_name == 'push' | ||
| uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
|
|
||
| # pipefail that pipes break | ||
| set -euo pipefail | ||
|
|
||
| export PATH="$HOME/.local/bin/:$PATH" | ||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
|
|
||
| MANAGED="${MANAGED:-${PWD}/platform-components/helm}" | ||
| CONFIG_FILE="${CONFIG_FILE:-config.yaml}" | ||
| CLUSTER_NAME="$(yq -r '.clusters[0].name' "$CONFIG_FILE")" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tiny thing: |
||
| CONFIGS="${CONFIGS:-platform-configs/${CLUSTER_NAME}/helm}" | ||
| OUTPUT_FILE="${OUTPUT_FILE:-}" | ||
|
tuunit marked this conversation as resolved.
|
||
|
|
||
| [[ -f "$CONFIG_FILE" ]] || { echo "::error::Missing $CONFIG_FILE β run 'kubara generate' first (or cd into its output)"; exit 1; } | ||
| [[ -d "$MANAGED" ]] || { echo "::error::Missing $MANAGED β run 'kubara generate' first"; exit 1; } | ||
| command -v helm >/dev/null 2>&1 || { echo "::error::helm not found on PATH"; exit 1; } | ||
| command -v yq >/dev/null 2>&1 || { echo "::error::yq not found on PATH"; exit 1; } | ||
|
|
||
| KUBE_VERSION=$(yq -r '.clusters[0].terraform.kubernetesVersion' "$CONFIG_FILE") | ||
|
|
||
| PROMETHEUS_STATUS="$(yq -r '.clusters[0].services."kube-prometheus-stack".status // "disabled"' "$CONFIG_FILE")" | ||
|
|
||
| # helm template flags advertise the monitoring API only when | ||
| # kube-prometheus-stack is enabled, since some charts (eg. traefik) render | ||
| # ServiceMonitors guarded by a `fail` on monitoring.coreos.com/v1. | ||
| HELM_TEMPLATE_ARGS=(--kube-version "$KUBE_VERSION" --include-crds) | ||
| if [[ "$PROMETHEUS_STATUS" == enabled ]]; then | ||
| HELM_TEMPLATE_ARGS+=(--api-versions "monitoring.coreos.com/v1") | ||
| fi | ||
|
|
||
|
|
||
| echo "Rendering charts from $MANAGED (kube-version=$KUBE_VERSION)" >&2 | ||
|
|
||
|
|
||
| render_dir="$(mktemp -d)"; trap 'rm -rf "$render_dir"' EXIT | ||
| FAILED=() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice that failures get collected in Could we fail (or at least emit a visible Minor: on the |
||
|
|
||
| for chart_path in "$MANAGED"/*/; do | ||
| chart=$(basename "$chart_path") | ||
| [[ -f "$chart_path/Chart.yaml" ]] || continue | ||
|
|
||
| # Don't render library charts | ||
| [[ "$(yq '.type // "application"' "$chart_path/Chart.yaml")" == library ]] && continue | ||
|
|
||
| echo "Updating dependency for ${chart_path}" >&2 | ||
|
|
||
| if ! dep_out=$(helm dependency update "$chart_path" >/dev/null 2>&1); then | ||
| echo "::error::helm dependency update failed for '$chart_path'"; echo "$dep_out" >&2 | ||
| FAILED+=("$chart:dependency-update"); continue | ||
| fi | ||
|
|
||
| values_file="$CONFIGS/$chart/values.generated.yaml" | ||
| base_values=(); [[ -f "$values_file" ]] && base_values=(-f "$values_file") | ||
|
|
||
| if ! helm template "${HELM_TEMPLATE_ARGS[@]}" \ | ||
| "$chart" "$chart_path" "${base_values[@]}" \ | ||
| > "$render_dir/$chart.yaml" 2> "$render_dir/$chart.err"; then | ||
| echo "::error::helm template for for '$chart':" | ||
| sed 's/^/ /' "$render_dir/$chart.err" >&2 | ||
| FAILED+=("$chart:template"); continue | ||
| fi | ||
| done | ||
|
|
||
| IMAGES="$( | ||
| cat "$render_dir"/*.yaml | | ||
| grep -E '^[[:space:]]*image:' | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quick note on coverage: since extraction is a
Not a blocker, but might be worth a comment noting this is best-effort, so "scan passed" isn't read as "every running image was scanned." |
||
| sed -E "s/^[[:space:]]*image:[[:space:]]*//; s/[\"']//g" | | ||
| grep -vE '[*!]' | # drop kyverno wildcard/negation entries | ||
| grep -vE '^[[:space:]]*$' | | ||
| sort -u | ||
| )" | ||
|
|
||
| echo "Done Rendering!" | ||
|
|
||
| [[ -n "$IMAGES" ]] || { echo "::warning::No image references found"; exit 0; } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With A |
||
|
|
||
| echo "$IMAGES" | ||
|
|
||
| if [[ -n "$OUTPUT_FILE" ]]; then | ||
| echo "$IMAGES" > "$OUTPUT_FILE" | ||
| echo "::notice::Image list written to $OUTPUT_FILE" | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,4 +49,14 @@ apply_yaml_if_set KUBARA_KUBERNETES_VERSION ".clusters[0].terraform.kubernetesV | |
| apply_yaml_if_set KUBARA_DNS_NAME ".clusters[0].dnsName" | ||
| apply_yaml_if_set KUBARA_DNS_NAME ".clusters[0].terraform.dns.name" | ||
|
|
||
| # Enable every catalog service to the image/vuln report and the release header cover all charts | ||
| yq eval '(.clusters[0].services[] | .status) = "enabled"' -i "$CFG" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the intent is to enable everything so all charts get rendered for the scan β makes sense π The catch: this same generated config is also consumed by the existing Could we scope the "enable all" to a separate config used only for the extract/scan step, so |
||
|
|
||
| # metalb, loki and velero need custom configs | ||
| yq eval '.clusters[0].services.metallb.config.publicLoadBalancerIPs = "203.0.113.10"' -i "$CFG" | ||
| yq eval '.clusters[0].services.metallb.config.loadBalancerAddressPool = ["203.0.113.0/24"]' -i "$CFG" | ||
| yq eval '.clusters[0].storage.bucketNames.chunks = "loki"' -i "$CFG" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This writes |
||
|
|
||
| yq eval '.clusters[0].services.velero.config.backupStorage.s3Url = "https://bucket.example.com"' -i "$CFG" | ||
|
tuunit marked this conversation as resolved.
|
||
|
|
||
| log "β config.yaml updated" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
severity: HIGHonly reports HIGH βCRITICALfindings are excluded from the SARIF. Did you meanseverity: HIGH,CRITICAL? (Combined withexit-code: '0'the scan is report-only, which is totally fine if that's intended.)