Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions config/examples/3rd-party-sec-scan-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---

qubership-jaeger:
- envoyproxy/envoy:v1.35.2
- ghcr.io/jaegertracing/spark-dependencies/spark-dependencies:latest
- jaegertracing/example-hotrod:1.74.0
# - jaegertracing/jaeger:2.11.0
# - jaegertracing/jaeger-cassandra-schema:1.74.0
# - jaegertracing/jaeger-es-index-cleaner:1.74.0
# - jaegertracing/jaeger-es-rollover:1.74.0
qubership-logging-operator:
- docker.io/alpine:3.21.3
- docker.io/fluent/fluent-bit:4.0.1
# - docker.io/graylog/graylog:5.2.12
# - docker.io/mongo:5.0.31
# - fluent/fluent-bit:3.0.6
# - ghcr.io/jimmidyson/configmap-reload:v0.13.1
# - ghcr.io/jimmidyson/configmap-reload:v0.15.0
# - graylog/graylog:5.2.7
# - mongo:5.0.19
qubership-monitoring-operator:
- docker.io/bloomberg/goldpinger:3.10.2
- docker.io/grafana/grafana:11.6.5
# - docker.io/grafana/grafana-image-renderer:3.12.9
# - docker.io/jimmidyson/configmap-reload:v0.5.0
# - docker.io/joeelliott/cert-exporter:v2.14.0
# - docker.io/prom/alertmanager:v0.28.1
# - docker.io/prom/blackbox-exporter:v0.27.0
# - docker.io/prom/cloudwatch-exporter:v0.16.0
# - docker.io/prom/node-exporter:v1.9.0
# - docker.io/prom/prometheus:v3.2.1
# - docker.io/prom/pushgateway:v1.11.0
# - docker.io/prometheuscommunity/json-exporter:v0.7.0
# - docker.io/prometheuscommunity/stackdriver-exporter:v0.18.0
# - docker.io/victoriametrics/operator:config-reloader-v0.63.0
# - docker.io/victoriametrics/operator:v0.63.0
# - docker.io/victoriametrics/victoria-metrics:v1.126.0
# - docker.io/victoriametrics/vmagent:v1.126.0
# - docker.io/victoriametrics/vmalert:v1.126.0
# - docker.io/victoriametrics/vmauth:v1.126.0
# - docker.io/victoriametrics/vminsert:v1.126.0-cluster
# - docker.io/victoriametrics/vmselect:v1.126.0-cluster
# - docker.io/victoriametrics/vmstorage:v1.126.0-cluster
# - gcr.io/stackdriver-prometheus/stackdriver-prometheus-sidecar:0.8.0
# - ghcr.io/jimmidyson/configmap-reload:v0.14.0
# - ghcr.io/tomkerkhove/promitor-agent-resource-discovery:0.13.0
# - ghcr.io/tomkerkhove/promitor-agent-scraper:2.13.0
# - quay.io/grafana-operator/grafana-operator:v4.9.0
# - quay.io/jacksontj/promxy:v0.0.92
# - quay.io/prometheus-operator/prometheus-config-reloader:v0.80.1
# - quay.io/prometheus-operator/prometheus-operator:v0.80.1
# - registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.15.0
178 changes: 178 additions & 0 deletions workflow-templates/3rd-party-sec-scan.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---

# Workflow to scan Docker images vulnerabilities by Grape and Trivy
# To make it work create a configuration file .qubership/3rd-party-sec-scan-config.yaml
# Example configuration file can be found there: config/examples/3rd-party-sec-scan-config.yaml
name: Security Scan Docker images
run-name: >
Security Scan
on:
workflow_dispatch:
inputs:
only-high-critical:
description: "Scope only HIGH + CRITICAL"
required: false
default: true
type: boolean
trivy-scan:
description: "Trivy scan"
required: false
default: true
type: boolean
grype-scan:
description: "Grype scan"
required: false
default: true
type: boolean
continue-on-error:
description: "Continue on error"
required: false
default: true
type: boolean
only-fixed:
description: "Ignore unfixed vulnerabilities"
required: false
default: true
type: boolean
schedule:
- cron: "0 3 * * 0" # every Sunday at 03:00 UTC
permissions:
contents: read

env:
CONFIG_FILE: .qubership/3rd-party-sec-scan-config.yaml
REPORT_BRANCH: reports
jobs:
load-config:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.config.outputs.packages }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Read config
id: config
run: |
echo "only-high-critical: ${{ inputs.only-high-critical }}"
echo "trivy-scan: ${{ inputs.trivy-scan }}"
echo "grype-scan: ${{ inputs.grype-scan }}"
echo "continue-on-error: ${{ inputs.continue-on-error }}"
echo "only-fixed: ${{ inputs.only-fixed }}"
echo "1. ==================================================================================="
yq -oj '.' $CONFIG_FILE
echo "2. ==================================================================================="
yq -oj '.' $CONFIG_FILE | jq -c 'to_entries | map({repo: .key, image: .value[]}) | {packages: .}'
echo "3. ==================================================================================="

packages=$(yq -oj '.' $CONFIG_FILE | jq -c 'to_entries | map({repo: .key, image: .value[]})')
echo "packages=$packages" >> $GITHUB_OUTPUT

security-scan-matrix:
needs: load-config
permissions:
security-events: write
contents: read
packages: read
strategy:
fail-fast: false
matrix:
package: "${{ fromJson(needs.load-config.outputs.packages) }}"
name: "${{ matrix.package.image }}"
uses: netcracker/qubership-workflow-hub/.github/workflows/re-security-scan.yml@v2.0.10
with:
target: 'docker'
image: ${{ matrix.package.image }}
only-high-critical: ${{ (github.event_name == 'schedule' && true) || inputs.only-high-critical }}
trivy-scan: ${{ (github.event_name == 'schedule' && true) || inputs.trivy-scan }}
grype-scan: ${{ (github.event_name == 'schedule' && true) || inputs.grype-scan }}
continue-on-error: ${{ (github.event_name == 'schedule' && true) || inputs.continue-on-error }}
only-fixed: ${{ (github.event_name == 'schedule' && true) || inputs.only-fixed }}
upload-sarif-to-security: false

create-report:
needs: [security-scan-matrix]
if: always()
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v5
with:
path: repo
persist-credentials: true
fetch-depth: 0

- name: Ensure branch exists
working-directory: repo
run: |
if git ls-remote --exit-code --heads origin "${{ env.REPORT_BRANCH }}" >/dev/null 2>&1; then
git fetch origin "${{ env.REPORT_BRANCH }}"
git checkout "${{ env.REPORT_BRANCH }}"
else
git checkout -b "${{ env.REPORT_BRANCH }}"
git push -u origin "${{ env.REPORT_BRANCH }}"
fi

- name: Download artifacts
uses: actions/download-artifact@v7
with:
pattern: '*.sarif'
path: ./sarif
merge-multiple: true

- name: Generate report
env:
ACTOR: ${{ github.actor }}
run: |
### Generating CSV report
mkdir -p repo
cur_date=$(date +%Y-%m-%d)
cur_time=$(date +%H-%M-%S)
cur_date_time=${cur_date}_${cur_time}
report_file_name=report-${cur_date_time}.csv
report_dir=repo/reports/${cur_date}
mkdir -p $report_dir
report_file_path=${report_dir}/${report_file_name}
echo "Report file path: ${report_file_path}"
for component in $(yq e 'keys[]' repo/${CONFIG_FILE}); do
echo "Processing $component's images..."
images=$(yq e ".${component}[]" repo/${CONFIG_FILE})
for image in $images; do
echo "Image: $image"
SHORT_NAME=${image##*/}
SAFE_NAME=${SHORT_NAME//:/_}
SAFE_NAME=${SAFE_NAME//\//_}
SAFE_NAME=${SAFE_NAME//-/_}
echo "Safe name: $SAFE_NAME"
ls -la ./sarif
echo "[DEBUG]: find ./sarif -name grype-${SAFE_NAME}*.csv -o -name trivy-${SAFE_NAME}*.csv"

for f in $(find ./sarif -name grype-${SAFE_NAME}*.csv -o -name trivy-${SAFE_NAME}*.csv); do
echo "File: $f"
echo "\"Componenet\",$(head -n 1 "$f")" > "${f}__new"
tail -n +2 "$f" | sed "s/^/\"${component}\",/" >> "${f}__new"
done
done
done
:> ${report_file_path}
i=0
for f in $(find ./sarif -name *.csv__new | sort); do
if [ $i -eq 0 ]; then
cat $f >> ${report_file_path}
else
tail -n +2 $f >> ${report_file_path}
fi
i=$((i + 1))
done

- name: Commit and Push Report
env:
ACTOR: ${{ github.actor }}
run: |
cd repo
git config --global user.name "$ACTOR"
git config --global user.email "$ACTOR@users.noreply.github.com"
git add .
git commit -m "CSV report ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" || echo "No changes"
git push origin "${REPORT_BRANCH}"
Loading