Skip to content

feat(vuln-reports): redesign workload and node CVE report emails - #22824

Draft
sthadka wants to merge 1 commit into
masterfrom
feature/redesign-cve-report-email
Draft

sthadka wants to merge 1 commit into
masterfrom
feature/redesign-cve-report-email

Conversation

@sthadka

@sthadka sthadka commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Description

Redesigns the notification email for Workload (image) CVE reports and Node CVE reports.

Problem: the report email rendered as a flat Heading: value list with the branding logo hardcoded at 20% width above the body. It didn't match the in-product look, gave recipients no quick signal of severity or CVE counts, and offered no way back to the report in the console.

Solution: the email body is now an email-safe HTML document (table layout, inline styles only, 600px container, light mode) that mirrors the UI:

  • branding logo in a header band + a titled dark bar
  • headline stat cards for deployed/watched (workload) or total (node) CVE counts
  • a severity legend using the product's PatternFly v6 severity colors (colored dot + label; independent of the counts — no invented per-severity split)
  • a config-details table using the exact UI field labels (CVE severity, CVE status, Image type, CVEs discovered in image since, ...)
  • an attachment note that reflects whether a CSV/ZIP is actually attached (none is sent when no CVEs are found)
  • a View report in console button, built from the notifier's UI endpoint + the report config ID

Notes / considered alternatives:

  • Severity colors are inlined as hex because email clients can't resolve PatternFly CSS custom properties; severityColorByValue is kept in sync with the UI (ui/apps/platform/src/constants/severityColors.ts).
  • writeContentBytes no longer wraps report bodies in a hardcoded <img>/<div> shell; the body now supplies its own HTML and references the inline logo via cid:logo.png. This only affects report emails (the sole EmbedLogo caller).
  • Considered filled severity "pills" but switched to dot + label: the light severities (Moderate/Low/Unknown) fail contrast as filled chips, and dot+label matches the UI's icon+label treatment.
  • User-provided values (config/collection names, filter queries, scope rules) are now HTML-escaped.
  • No feature flag: this is a cosmetic change to an existing notification. Happy to gate it if reviewers prefer.

Design was iterated as static HTML mockups (workload, all render variants, node) before implementation. See "How I validated" for how to preview.

User-facing documentation

Testing and quality

  • the change is production ready: the change is GA, or otherwise the functionality is gated by a feature flag
  • CI results are inspected

Automated testing

  • added unit tests
  • added e2e tests
  • added regression tests
  • added compatibility tests
  • modified existing tests

How I validated my change

  • go build ./central/reports/scheduler/v2/reportgenerator/... ./central/notifiers/email/ — passes
  • go vet on the same packages — passes
  • go test ./central/reports/scheduler/v2/reportgenerator/ ./central/reports/scheduler/v2/reportgenerator/node/ ./central/notifiers/email/ — passes
  • New unit tests cover: collection scope, entity/custom scope (raw filter query + scope rules), the no-vulns variant, HTML escaping of user values, the console-link builder, and thousands-separator formatting.
  • Rendered the HTML mockups locally and reviewed all variants (with CVEs / no CVEs, collection vs custom scope, single vs both image types, all five severities, node reports). Screenshots below.

This PR was partially generated with the help of an AI agent.

image image

Problem: the workload/node CVE report notification email rendered as a flat
"Heading: value" list with the branding logo hardcoded at 20% width above the
body. It didn't match the in-product look and gave recipients no quick signal
of severity or CVE counts, and no way back to the report in the console.

Solution: build the email body as an email-safe HTML document (table layout,
inline styles only, 600px container, light mode) that mirrors the UI:
- branding logo in a header band + a titled dark bar
- headline stat cards for deployed/watched (workload) or total (node) CVEs
- a severity legend using the product's PatternFly v6 severity colors
  (dot + label; independent of the counts, no invented per-severity split)
- a config-details table using the exact UI field labels
- an attachment note that reflects whether a CSV/ZIP is actually attached
  (none is sent when no CVEs are found)
- a "View report in console" button built from the notifier's UI endpoint and
  the report config ID

Notes:
- Colors are inlined as hex because email clients can't resolve PatternFly CSS
  custom properties; severityColorByValue is kept in sync with the UI.
- writeContentBytes no longer wraps report bodies in an <img>/<div> shell; the
  body now supplies its own HTML and references the inline logo via cid:logo.png.
- User-provided values (config/collection names, filter queries, scope rules)
  are now HTML-escaped.

Associated request: "I get a weekly 'RHACS Workload CVE Report' email; make it
look much nicer" -> iterated on HTML mockups (workload, all cases, node), then
implemented the approved design.

Note: partially generated with the help of an AI agent.
@openshift-ci

openshift-ci Bot commented Sep 14, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: e10e1d63-19d0-4dbb-b153-4e325859c650

📥 Commits

Reviewing files that changed from the base of the PR and between 241cf27 and e88cf82.

📒 Files selected for processing (7)
  • central/notifiers/email/email.go
  • central/notifiers/email/email_test.go
  • central/reports/scheduler/v2/reportgenerator/email_formatter.go
  • central/reports/scheduler/v2/reportgenerator/email_formatter_test.go
  • central/reports/scheduler/v2/reportgenerator/email_html.go
  • central/reports/scheduler/v2/reportgenerator/node/report_gen_impl.go
  • central/reports/scheduler/v2/reportgenerator/report_gen_impl.go

Included review availability: Your plan provides up to 12 included reviews per hour; 9 remain after this review.


📝 Summary

Summary by CodeRabbit

  • New Features

    • Redesigned workload and node vulnerability report emails with consistent HTML layouts, summaries, severity details, attachment status, and optional console links.
    • Added report links to generated notification emails.
    • Improved number formatting and presentation of report details.
    • Preserved support for custom email subjects and bodies.
  • Bug Fixes

    • Email bodies are now emitted as complete HTML content without unwanted wrapper elements.
    • Improved handling of formatting errors so affected notifications are skipped safely.

Walkthrough

Report emails now use shared HTML layouts for workload and node notifications. Report generators build notifier-specific URLs and format bodies with attachment and vulnerability details. Email delivery writes the complete HTML body without adding an image wrapper.

Changes

Report email rendering

Layer / File(s) Summary
Shared report email layout
central/reports/scheduler/v2/reportgenerator/email_html.go
Adds styled HTML rendering for titles, introductions, statistics, severity details, configuration data, attachment status, console links, and footers.
Workload and node report formatting
central/reports/scheduler/v2/reportgenerator/email_formatter.go, central/reports/scheduler/v2/reportgenerator/email_formatter_test.go
Adds workload and node body formatters, report URL builders, integer formatting, scope details, escaping, conditional sections, and validation tests.
Notifier integration and direct HTML delivery
central/reports/scheduler/v2/reportgenerator/report_gen_impl.go, central/reports/scheduler/v2/reportgenerator/node/report_gen_impl.go, central/notifiers/email/email.go, central/notifiers/email/email_test.go
Formats each notifier body, records formatting errors, tracks attachment state, and sends complete HTML bodies without generated image wrappers. Tests expect direct HTML content with CRLF termination.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant ReportGenerator
  participant FormatWorkloadReportEmailBody
  participant ReportEmailHTML
  participant EmailNotifier
  ReportGenerator->>FormatWorkloadReportEmailBody: pass report data and notifier URL
  FormatWorkloadReportEmailBody->>ReportEmailHTML: render shared HTML layout
  ReportEmailHTML-->>FormatWorkloadReportEmailBody: return complete HTML body
  FormatWorkloadReportEmailBody-->>ReportGenerator: return body or formatting error
  ReportGenerator->>EmailNotifier: send complete HTML body
Loading

Suggested reviewers: charmik-redhat

Merge Risk: ⚪ Minimal · up to e88cf

The report-email redesign has no identified correctness, security, or delivery issue requiring changes before merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 7 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main change: redesigning workload and node CVE report emails.
Description check ✅ Passed The description follows the template, explains the problem and solution, documents user-facing behavior, lists testing changes, and provides build, vet, unit-test, and manual validation details. Sever…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/redesign-cve-report-email

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.16592% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.81%. Comparing base (b625dd4) to head (e88cf82).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
...ts/scheduler/v2/reportgenerator/report_gen_impl.go 0.00% 14 Missing ⚠️
...heduler/v2/reportgenerator/node/report_gen_impl.go 0.00% 12 Missing ⚠️
...ts/scheduler/v2/reportgenerator/email_formatter.go 88.88% 5 Missing and 5 partials ⚠️
...reports/scheduler/v2/reportgenerator/email_html.go 94.39% 3 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #22824      +/-   ##
==========================================
- Coverage   51.82%   51.81%   -0.01%     
==========================================
  Files        2901     2902       +1     
  Lines      182788   182951     +163     
==========================================
+ Hits        94721    94801      +80     
- Misses      79776    79835      +59     
- Partials     8291     8315      +24     
Flag Coverage Δ
go-unit-tests 51.81% <81.16%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Build Images Ready

Images are ready for commit e88cf82. To use with deploy scripts:

export MAIN_IMAGE_TAG=5.0.x-292-ge88cf82c97

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant