Skip to content

Commit d6f7093

Browse files
authored
Workflow to trigger Scan report (#632)
1 parent e9f6181 commit d6f7093

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
name: Vulnerability Scan Daily
2+
on:
3+
schedule:
4+
- cron: '0 0 * * *'
5+
6+
jobs:
7+
build:
8+
name: Build and scan image
9+
runs-on: ubuntu-latest
10+
env:
11+
DOCKER_IMAGE: newrelic/infrastructure-bundle
12+
DOCKER_IMAGE_TAG: ci
13+
TRIVY_DISABLE_VEX_NOTICE: "true"
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up QEMU
18+
uses: docker/setup-qemu-action@v3
19+
- name: Set up Docker Buildx
20+
uses: docker/setup-buildx-action@v3
21+
- uses: actions/setup-go@v5
22+
with:
23+
go-version-file: go.mod
24+
- name: Download integrations
25+
run: go run downloader.go
26+
27+
- name: Build and load docker image
28+
run: |
29+
DOCKER_PLATFORMS=linux/amd64 ./docker-build.sh . --load
30+
31+
# ... (previous steps: checkout, setup-go, build docker image) ...
32+
33+
- name: Create Scan Template
34+
run: |
35+
cat << 'EOF' > scan.tpl
36+
{{- range . -}}
37+
{{- $target := .Target -}}
38+
{{- range .Vulnerabilities -}}
39+
{{ $target }} | {{ .PkgName }} | {{ .VulnerabilityID }} | {{ .Severity }} | {{ .FixedVersion }}
40+
{{ end -}}
41+
{{- end -}}
42+
EOF
43+
44+
- name: Run Trivy Scan
45+
uses: aquasecurity/trivy-action@0.29.0
46+
with:
47+
image-ref: ${{ env.DOCKER_IMAGE }}:${{ env.DOCKER_IMAGE_TAG }}
48+
format: 'template'
49+
template: '@scan.tpl'
50+
ignore-unfixed: true
51+
severity: "CRITICAL,HIGH,MEDIUM,LOW"
52+
output: "trivy-report.txt"
53+
54+
- name: Run Grype Scan
55+
uses: anchore/scan-action@v6
56+
id: grype
57+
with:
58+
image: "${{ env.DOCKER_IMAGE }}:${{ env.DOCKER_IMAGE_TAG }}"
59+
fail-build: false
60+
severity-cutoff: low
61+
only-fixed: true
62+
output-format: json # Use JSON for raw data
63+
64+
- name: Convert Grype to Table Format & Merge
65+
run: |
66+
# 1. Use jq to convert Grype JSON to the same format: Target | Pkg | CVE | Severity | Fixed
67+
# We use "any" for Fixed Version if not explicitly found to keep column count consistent
68+
jq -r '.matches[] | "\(.artifact.locations[0].path) | \(.artifact.name) | \(.vulnerability.id) | \(.vulnerability.severity | ascii_upcase) | \(.vulnerability.fix.versions[0] // "n/a")"' ${{ steps.grype.outputs.json }} > grype-report.txt || touch grype-report.txt
69+
70+
# 2. Merge both reports
71+
cat trivy-report.txt grype-report.txt > combined-raw.txt
72+
73+
# 3. Clean up the paths and de-duplicate unique CVEs per integration
74+
# This ensures that if both find the same CVE in the same binary, we only count it once
75+
sed -i 's|var/db/newrelic-infra/newrelic-integrations/bin/||g' combined-raw.txt
76+
sort -u combined-raw.txt -o raw-report.txt
77+
78+
- name: Format Slack Message
79+
id: format_message
80+
run: |
81+
# 1. Clean the report
82+
sed -i '/^[[:space:]]*$/d' raw-report.txt
83+
84+
if [ -s raw-report.txt ]; then
85+
# --- LOGIC: GLOBAL COUNTS (Strictly Cleaned) ---
86+
# We use head -n 1 to ensure only one line is grabbed
87+
# We use sed to strip any non-numeric characters
88+
TOTAL_CVE_COUNT=$(grep -c "CVE-" raw-report.txt | head -n 1 | sed 's/[^0-9]//g')
89+
UNIQUE_INT_COUNT=$(cut -d'|' -f1 raw-report.txt | sort -u | wc -l | head -n 1 | sed 's/[^0-9]//g')
90+
CRIT_T=$(grep -c "CRITICAL" raw-report.txt | head -n 1 | sed 's/[^0-9]//g')
91+
HIGH_T=$(grep -c "HIGH" raw-report.txt | head -n 1 | sed 's/[^0-9]//g')
92+
MED_T=$(grep -c "MEDIUM" raw-report.txt | head -n 1 | sed 's/[^0-9]//g')
93+
LOW_T=$(grep -c "LOW" raw-report.txt | head -n 1 | sed 's/[^0-9]//g')
94+
95+
# Fallback to 0 if variables are empty
96+
TOTAL_CVE_COUNT=${TOTAL_CVE_COUNT:-0}
97+
UNIQUE_INT_COUNT=${UNIQUE_INT_COUNT:-0}
98+
CRIT_T=${CRIT_T:-0}
99+
HIGH_T=${HIGH_T:-0}
100+
MED_T=${MED_T:-0}
101+
LOW_T=${LOW_T:-0}
102+
103+
# --- LOGIC: PER-INTEGRATION AGGREGATION ---
104+
AGGREGATED_TABLE=$(awk -F'|' '
105+
{
106+
name = $1;
107+
gsub(/.*\//, "", name); gsub(/ /, "", name);
108+
sev = $4; gsub(/ /, "", sev);
109+
110+
ints[name]++;
111+
if (sev == "CRITICAL") crit[name]++;
112+
else if (sev == "HIGH") high[name]++;
113+
else if (sev == "MEDIUM") med[name]++;
114+
else if (sev == "LOW") low[name]++;
115+
}
116+
END {
117+
for (i in ints) {
118+
if (crit[i] > 0) icon = "🔴";
119+
else if (high[i] > 0) icon = "🟠";
120+
else if (med[i] > 0) icon = "🟡";
121+
else icon = "🔵";
122+
row_tot = (crit[i]+0) + (high[i]+0) + (med[i]+0) + (low[i]+0);
123+
printf "%s %-12s | %2d | %2d | %2d | %2d | %3d\n", icon, substr(i,1,12), crit[i], high[i], med[i], low[i], row_tot
124+
}
125+
}' raw-report.txt | sort -r)
126+
127+
# --- CONSTRUCT DASHBOARD ---
128+
{
129+
echo "SLACK_MESSAGE<<EOF"
130+
echo -e "*🛡️ SECURITY SCAN REPORT* | \`$(date +'%Y-%m-%d')\`"
131+
echo -e "*Multi-Engine:* _Trivy & Grype Combined_"
132+
echo -e "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
133+
echo -e "*📊 OVERALL POSTURE*"
134+
echo -e "• *Total Issues:* \`$TOTAL_CVE_COUNT\` findings across \`$UNIQUE_INT_COUNT\` components"
135+
echo -e "• *Critical:* 🔴 \`$CRIT_T\` | *High:* 🟠 \`$HIGH_T\`"
136+
echo -e "• *Medium:* 🟡 \`$MED_T\` | *Low:* 🔵 \`$LOW_T\`"
137+
echo -e "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
138+
echo -e "*🔎 FINDINGS BREAKDOWN:*"
139+
echo -e "\`\`\`"
140+
echo -e "ST INTEGRATION | CR | HI | ME | LO | TOT"
141+
echo -e "--- ------------ | -- | -- | -- | -- | ---"
142+
echo -e "$AGGREGATED_TABLE"
143+
echo -e "\`\`\`"
144+
echo -e "🔗 _Check GitHub Actions for more details._"
145+
echo "EOF"
146+
} >> $GITHUB_OUTPUT
147+
else
148+
echo "SLACK_MESSAGE=*✅ SECURITY SCAN PASSED* - No issues detected." >> $GITHUB_OUTPUT
149+
fi
150+
151+
- name: Send Slack notification
152+
uses: archive/github-actions-slack@master
153+
with:
154+
slack-bot-user-oauth-access-token: ${{ secrets.COREINT_SLACK_TOKEN }}
155+
slack-channel: ${{ secrets.COREINT_SLACK_CHANNEL }}
156+
slack-text: ${{ steps.format_message.outputs.SLACK_MESSAGE }}
157+
slack-optional-parse: full

0 commit comments

Comments
 (0)