Skip to content

ROX-33654: Add entity scope and query field support to report service#19861

Open
c-du wants to merge 1 commit intomasterfrom
cong/filterapi
Open

ROX-33654: Add entity scope and query field support to report service#19861
c-du wants to merge 1 commit intomasterfrom
cong/filterapi

Conversation

@c-du
Copy link
Copy Markdown
Contributor

@c-du c-du commented Apr 7, 2026

Description

Adds support for two new fields in the vulnerability report service (v2
API):

  • Entity scope: an alternative to
    collection-based scoping that lets callers filter by
    cluster/namespace/deployment entity rules directly, without needing a
    pre-created collection.
  • Query field: a free-form search query
    string appended to CVE filter criteria.

Changes are confined to the service and validation layers:

  • Bidirectional conversion (API ↔ storage) for entity scope in
    convertV2ResourceScopeToProto / convertProtoResourceScopeToV2
  • Query field passthrough in vuln filter conversion
  • ResourceScope stored in report snapshots
  • Validation of entity scope rules (unset entity/field, duplicate
    entity+field pairs, cluster annotation unsupported, label key=value format,
    query parseable via search.ParseQuery)

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
  • modified existing tests

How I validated my change

  • Unit tests added for new validation paths (TestValidateEntityScope,
    TestValidateReportFiltersQuery)
  • Unit tests added for bidirectional entity scope conversion
    (TestConvertEntityScope)
  • All central/reports/ unit tests pass

- Add bidirectional conversion between API and storage for entity scope
  resource scope type in report configurations and snapshots
- Add query field passthrough in vulnerability report filters
- Add validation for entity scope rules (unset entity/field, duplicate
  entity+field pairs, cluster annotation unsupported, label key=value format)
- Add query field validation using search.ParseQuery
- Store ResourceScope in report snapshot

Partially generated with AI assistance.
@c-du c-du requested a review from a team as a code owner April 7, 2026 13:22
@c-du c-du requested a review from ksurabhi91 April 7, 2026 13:23
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 7, 2026

Codecov Report

❌ Patch coverage is 69.74790% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 49.61%. Comparing base (3580bb4) to head (9af5987).
⚠️ Report is 15 commits behind head on master.

Files with missing lines Patch % Lines
central/reports/validation/validate.go 58.73% 26 Missing ⚠️
central/reports/service/v2/convert.go 82.14% 7 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #19861      +/-   ##
==========================================
+ Coverage   49.60%   49.61%   +0.01%     
==========================================
  Files        2763     2763              
  Lines      208339   208428      +89     
==========================================
+ Hits       103346   103417      +71     
- Misses      97327    97339      +12     
- Partials     7666     7672       +6     
Flag Coverage Δ
go-unit-tests 49.61% <69.74%> (+0.01%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 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

github-actions bot commented Apr 7, 2026

🚀 Build Images Ready

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

export MAIN_IMAGE_TAG=4.11.x-566-g9af5987db7

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Vulnerability reports now support entity-based resource scoping for granular filtering beyond collections.
    • Added query field support for vulnerability report filters, enabling advanced search functionality.
    • Enhanced validation for report configurations including entity scope rules and search queries.
  • Tests

    • Added comprehensive test coverage for entity scope conversions and query validation.

Walkthrough

The changes extend the central/reports service's vulnerability report handling to support entity-scoped resource configurations alongside collection-scoped ones. This includes bidirectional conversion between API v2 and storage representations, validation logic for entity scope rules, and Query field parsing for vulnerability report filters.

Changes

Cohort / File(s) Summary
Conversion Logic
central/reports/service/v2/convert.go
Added bidirectional converters for EntityScope (mapping between apiV2.EntityScope and storage.EntityScope). Extended convertV2ResourceScopeToProto and convertProtoResourceScopeToV2 with type-switch routing for both CollectionScope and EntityScope. Added Query field mapping in vulnerability report filters. Updated convertProtoReportSnapshotstoV2 to populate resource scope in report snapshots.
Conversion Tests
central/reports/service/v2/convert_test.go
Added TestConvertEntityScope with bidirectional conversion coverage for entity scopes and round-trip assertions. Verified convertProtoResourceScopeToV2 handles entity scope variants without triggering unnecessary datastore access. Asserts Query field persistence through filter conversions.
Validation Logic
central/reports/validation/validate.go
Refactored validateResourceScope to route collection and entity scope validation via separate helpers. Added validateCollectionScope (nil/empty checks, existence verification) and validateEntityScope (rule validation, entity/field checks, label format validation, uniqueness enforcement). Enhanced validateReportFilters to parse and validate Query field. Modified ValidateAndGenerateReportRequest to conditionally fetch collections only when collectionId is non-empty.
Validation Tests
central/reports/validation/validate_test.go
Added test helpers for constructing EntityScope and rules. Introduced TestValidateEntityScope with table-driven coverage for valid and invalid entity scope scenarios. Added TestValidateReportFiltersQuery for Query field validation with well-formed and malformed query assertions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding entity scope and query field support to the report service, matching the changeset across conversion and validation layers.
Description check ✅ Passed The description covers the main feature (entity scope and query field support), implementation details, and testing approach (unit tests added/modified). However, user-facing documentation and production-readiness checkboxes remain incomplete.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cong/filterapi

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
central/reports/validation/validate.go (1)

351-356: ⚠️ Potential issue | 🔴 Critical

Guard collection before populating CollectionSnapshot.

Line 353 dereferences collection unconditionally, but lines 284-295 now leave collection == nil for the new entity-scope path. The first valid entity-scoped report request will panic here before the snapshot is created, so the feature is effectively unusable.

🐛 Proposed fix
 	snapshot := &storage.ReportSnapshot{
 		ReportConfigurationId: config.GetId(),
 		Name:                  config.GetName(),
 		Description:           config.GetDescription(),
 		Type:                  storage.ReportSnapshot_VULNERABILITY,
-		Collection: &storage.CollectionSnapshot{
-			Id:   config.GetResourceScope().GetCollectionId(),
-			Name: collection.GetName(),
-		},
 		ResourceScope: config.GetResourceScope(),
 		Schedule:      config.GetSchedule(),
 		ReportStatus: &storage.ReportStatus{
 			RunState:                 storage.ReportStatus_WAITING,
 			ReportRequestType:        requestType,
 			ReportNotificationMethod: notificationMethod,
 		},
 	}
+	if collection != nil {
+		snapshot.Collection = &storage.CollectionSnapshot{
+			Id:   config.GetResourceScope().GetCollectionId(),
+			Name: collection.GetName(),
+		}
+	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@central/reports/validation/validate.go` around lines 351 - 356, The code
unconditionally dereferences collection when building the CollectionSnapshot
even though collection can be nil for entity-scoped requests; modify the
snapshot construction in validate.go so you only populate Collection:
&storage.CollectionSnapshot{...} when collection != nil (i.e., guard the access
to collection.GetName()/GetId()), otherwise leave Collection nil (or omit it) to
avoid a panic; update the block that sets Collection: to conditionally assign
based on collection and keep ResourceScope and Schedule assignments unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@central/reports/service/v2/convert.go`:
- Around line 483-486: The current conversion calls
convertProtoResourceScopeToV2 on snapshot.GetResourceScope(), which performs
live datastore collection lookups and can fail or rewrite historical names;
change the conversion logic to first build ResourceScope.CollectionScope from
snapshot.GetCollection() (use snapshot.GetCollection() to populate
CollectionScope fields) and only call convertProtoResourceScopeToV2 as a
fallback when snapshot.GetCollection() is empty/missing; implement this in a
new/updated helper (e.g., convertProtoSnapshotResourceScopeToV2) that accepts
the snapshot, prefers snapshot.GetCollection() for CollectionScope, and
delegates to convertProtoResourceScopeToV2(snapshot.GetResourceScope()) only
when snapshot collection metadata is absent.

---

Outside diff comments:
In `@central/reports/validation/validate.go`:
- Around line 351-356: The code unconditionally dereferences collection when
building the CollectionSnapshot even though collection can be nil for
entity-scoped requests; modify the snapshot construction in validate.go so you
only populate Collection: &storage.CollectionSnapshot{...} when collection !=
nil (i.e., guard the access to collection.GetName()/GetId()), otherwise leave
Collection nil (or omit it) to avoid a panic; update the block that sets
Collection: to conditionally assign based on collection and keep ResourceScope
and Schedule assignments unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: e3908763-42bc-4423-9b33-71e46f51d3e9

📥 Commits

Reviewing files that changed from the base of the PR and between b2a85fc and 9af5987.

📒 Files selected for processing (4)
  • central/reports/service/v2/convert.go
  • central/reports/service/v2/convert_test.go
  • central/reports/validation/validate.go
  • central/reports/validation/validate_test.go

Comment on lines +483 to +486
resourceScope, err := s.convertProtoResourceScopeToV2(snapshot.GetResourceScope())
if err != nil {
return nil, err
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use snapshot metadata instead of live collection lookups here.

Lines 483-486 now route snapshot ResourceScope through convertProtoResourceScopeToV2, which resolves collection-scoped names from the current datastore. That means one deleted collection will make the whole snapshot conversion fail, and a renamed collection will also rewrite the historical name, even though snapshot.GetCollection() already stores the snapshot-time metadata. Please build ResourceScope.CollectionScope from the snapshot copy first and only fall back to a live lookup when that snapshot metadata is absent.

💡 Suggested direction
-        resourceScope, err := s.convertProtoResourceScopeToV2(snapshot.GetResourceScope())
-        if err != nil {
-            return nil, err
-        }
+        resourceScope, err := s.convertProtoSnapshotResourceScopeToV2(
+            snapshot.GetResourceScope(),
+            snapshot.GetCollection(),
+        )
+        if err != nil {
+            return nil, err
+        }

convertProtoSnapshotResourceScopeToV2 should prefer snapshot.GetCollection() for collection-scoped snapshots so historical report reads stay stable after collection rename/deletion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@central/reports/service/v2/convert.go` around lines 483 - 486, The current
conversion calls convertProtoResourceScopeToV2 on snapshot.GetResourceScope(),
which performs live datastore collection lookups and can fail or rewrite
historical names; change the conversion logic to first build
ResourceScope.CollectionScope from snapshot.GetCollection() (use
snapshot.GetCollection() to populate CollectionScope fields) and only call
convertProtoResourceScopeToV2 as a fallback when snapshot.GetCollection() is
empty/missing; implement this in a new/updated helper (e.g.,
convertProtoSnapshotResourceScopeToV2) that accepts the snapshot, prefers
snapshot.GetCollection() for CollectionScope, and delegates to
convertProtoResourceScopeToV2(snapshot.GetResourceScope()) only when snapshot
collection metadata is absent.

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