Skip to content

feat(apis): add SubStatusNotEvaluated for missing-GVR skips#166

Merged
matthyx merged 2 commits into
kubescape:mainfrom
Sanchit2662:feat/substatus-not-evaluated
May 7, 2026
Merged

feat(apis): add SubStatusNotEvaluated for missing-GVR skips#166
matthyx merged 2 commits into
kubescape:mainfrom
Sanchit2662:feat/substatus-not-evaluated

Conversation

@Sanchit2662
Copy link
Copy Markdown
Contributor

@Sanchit2662 Sanchit2662 commented May 1, 2026

What this does

Adds a new SubStatusNotEvaluated skipped substatus so controls that get skipped because their required GVRs could not be collected (RBAC denied, missing CRDs, API errors) can be told apart from controls that were skipped for configuration / review reasons.

Right now everything ends up as a generic skipped, which makes it impossible for downstream consumers to filter on the actual cluster-gap case. Free-text info is not enough since you can't filter on it cleanly.

Why this is here and not in kubescape

This is the prerequisite piece for kubescape/kubescape#2010. The kubescape side wants to mark controls as notEvaluated when their GVRs fail to pull, but the substatus enum and the precedence logic both live here, so this has to land first.

Once this is released, kubescape will bump the dep and start setting the substatus from its resource collection path.

Changes

  • reporthandling/apis/statuses.go: new SubStatusNotEvaluated constant + SubStatusNotEvaluatedInfo message. Updated CompareStatusAndSubStatus so notEvaluated wins over the other skipped substatuses, since a real cluster/RBAC gap is more actionable than a configuration or review skip. failed still beats notEvaluated.
  • reporthandling/results/v1/reportsummary/controlsummarymethods.go: extended calculateNSetSubStatus skipped branch to handle the new substatus when aggregating control summaries.
  • reporthandling/apis/statuses_test.go: added precedence tests covering the new substatus against the existing skipped ones and against failed.

Out of scope

  • Anything that actually sets the new substatus. That happens in kubescape on top of the existing InfoMap work. Kept this PR to enum + precedence only so it's easy to review on its own.

Notes

  • No new external deps.
  • Existing tests pass: go test ./reporthandling/apis/... ./reporthandling/results/...
  • Additive only, doesn't change any existing substatus behavior.

Refs: kubescape/kubescape#2010

Summary by CodeRabbit

  • New Features

    • Added a "Not Evaluated" skipped status to indicate controls not evaluated due to unavailable resources.
  • Improvements

    • Status comparison now prioritizes "Not Evaluated" among skipped reasons and prevents it from being overwritten by configuration-missing logic.
  • Tests

    • Added test scenarios validating "Not Evaluated" precedence and preservation.
  • Chores

    • Extended mock data with "Not Evaluated" examples for validation.

Signed-off-by: Sanchit2662 <sanchit2662@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f3043041-6d53-41d0-94b9-fe1fb48648de

📥 Commits

Reviewing files that changed from the base of the PR and between 9d82ad6 and 7c68ed0.

📒 Files selected for processing (3)
  • reporthandling/results/v1/resourcesresults/controls.go
  • reporthandling/results/v1/resourcesresults/controls_test.go
  • reporthandling/results/v1/resourcesresults/datastructures_mock.go

📝 Walkthrough

Walkthrough

Adds a new skipped sub-status notEvaluated (with message) and updates status comparison, control summary, resource status-setting, mocks, and tests so notEvaluated takes precedence among skipped sub-statuses and is not overwritten by configuration-missing logic.

Changes

NotEvaluated sub-status introduction and propagation

Layer / File(s) Summary
Data / Constants
reporthandling/apis/statuses.go
Adds SubStatusNotEvaluated constant and SubStatusNotEvaluatedInfo message.
Status Comparison Core
reporthandling/apis/statuses.go
Updates CompareStatusAndSubStatus so when overall status is StatusSkipped, presence of SubStatusNotEvaluated in either input yields notEvaluated sub-status immediately (takes precedence over other skipped sub-statuses).
Resource Status Guard
reporthandling/results/v1/resourcesresults/controls.go
Changes ResourceAssociatedControl.SetStatus to avoid overwriting an existing SubStatusNotEvaluated when applying the "configuration missing" skip (only set SubStatusConfiguration if current sub-status is not SubStatusNotEvaluated).
Control Summary Application
reporthandling/results/v1/reportsummary/controlsummarymethods.go
calculateNSetSubStatus recognizes SubStatusNotEvaluated in inputs/current StatusInfo.SubStatus and sets StatusInfo.SubStatus and InnerInfo accordingly before falling back to configuration-based branch.
Mocks
reporthandling/results/v1/resourcesresults/datastructures_mock.go
Adds mockResourceAssociatedRuleNotEvaluated() and mockResourceAssociatedControlNotEvaluated() to produce skipped results with SubStatusNotEvaluated for testing.
Tests
reporthandling/apis/statuses_test.go, reporthandling/results/v1/resourcesresults/controls_test.go
Adds/updates test cases: verify SubStatusNotEvaluated overrides other skipped sub-statuses in comparison, confirm StatusFailed remains higher priority, and ensure notEvaluated is preserved (not overridden) by configuration-missing logic and interacts correctly with GVR collection-gap behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I peeked at statuses under dew-lit leaves,
No resources found, so the bunny believes—
"Not evaluated!" I softly declare,
Preserve that state with careful care,
A hop, a note, and tidy reprieves.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(apis): add SubStatusNotEvaluated for missing-GVR skips' clearly and specifically describes the main change: adding a new substatus constant for distinguishing controls skipped due to missing GVRs.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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.

Caution

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

⚠️ Outside diff range comments (1)
reporthandling/results/v1/reportsummary/controlsummarymethods.go (1)

65-78: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align skipped-substatus precedence with CompareStatusAndSubStatus (and handle integration).

Line 72 onward omits SubStatusIntegration, and manual review is checked before requires review. That diverges from reporthandling/apis/statuses.go (CompareStatusAndSubStatus) and can yield inconsistent aggregate substatuses across code paths.

Suggested patch
 	case apis.StatusSkipped:
 		if subStatus == apis.SubStatusNotEvaluated || controlSummary.StatusInfo.SubStatus == apis.SubStatusNotEvaluated {
 			controlSummary.StatusInfo.SubStatus = apis.SubStatusNotEvaluated
 			controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusNotEvaluatedInfo)
 		} else if subStatus == apis.SubStatusConfiguration || controlSummary.StatusInfo.SubStatus == apis.SubStatusConfiguration {
 			controlSummary.StatusInfo.SubStatus = apis.SubStatusConfiguration
 			controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusConfigurationInfo)
-		} else if subStatus == apis.SubStatusManualReview || controlSummary.StatusInfo.SubStatus == apis.SubStatusManualReview {
-			controlSummary.StatusInfo.SubStatus = apis.SubStatusManualReview
-			controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusManualReviewInfo)
+		} else if subStatus == apis.SubStatusIntegration || controlSummary.StatusInfo.SubStatus == apis.SubStatusIntegration {
+			controlSummary.StatusInfo.SubStatus = apis.SubStatusIntegration
+			controlSummary.StatusInfo.InnerInfo = ""
 		} else if subStatus == apis.SubStatusRequiresReview || controlSummary.StatusInfo.SubStatus == apis.SubStatusRequiresReview {
 			controlSummary.StatusInfo.SubStatus = apis.SubStatusRequiresReview
 			controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusRequiresReviewInfo)
+		} else if subStatus == apis.SubStatusManualReview || controlSummary.StatusInfo.SubStatus == apis.SubStatusManualReview {
+			controlSummary.StatusInfo.SubStatus = apis.SubStatusManualReview
+			controlSummary.StatusInfo.InnerInfo = string(apis.SubStatusManualReviewInfo)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@reporthandling/results/v1/reportsummary/controlsummarymethods.go` around
lines 65 - 78, In the apis.StatusSkipped branch (case apis.StatusSkipped) the
precedence and coverage for skipped substatuses diverges from
CompareStatusAndSubStatus: add a branch to handle apis.SubStatusIntegration (set
controlSummary.StatusInfo.SubStatus = apis.SubStatusIntegration and InnerInfo =
string(apis.SubStatusIntegrationInfo)) and reorder the checks so
apis.SubStatusRequiresReview is evaluated before apis.SubStatusManualReview to
match CompareStatusAndSubStatus; keep comparisons against both the local
subStatus variable and controlSummary.StatusInfo.SubStatus and update InnerInfo
values for each substatus accordingly.
🧹 Nitpick comments (1)
reporthandling/apis/statuses_test.go (1)

33-38: ⚡ Quick win

Expand precedence tests to cover integration and requires review.

Line 33 says “other skipped substatuses,” but current additions only assert configuration/manual-review cases. Add explicit checks against SubStatusIntegration and SubStatusRequiresReview to lock the full precedence contract.

Suggested test additions
 	// notEvaluated should win over other skipped substatuses since it signals a real cluster/RBAC gap
 	assert.Equal(t, makeIS(StatusSkipped, SubStatusNotEvaluated), makeIS(CompareStatusAndSubStatus(StatusSkipped, StatusPassed, SubStatusNotEvaluated, SubStatusUnknown)))
 	assert.Equal(t, makeIS(StatusSkipped, SubStatusNotEvaluated), makeIS(CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusNotEvaluated, SubStatusConfiguration)))
 	assert.Equal(t, makeIS(StatusSkipped, SubStatusNotEvaluated), makeIS(CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusManualReview, SubStatusNotEvaluated)))
+	assert.Equal(t, makeIS(StatusSkipped, SubStatusNotEvaluated), makeIS(CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusIntegration, SubStatusNotEvaluated)))
+	assert.Equal(t, makeIS(StatusSkipped, SubStatusNotEvaluated), makeIS(CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusRequiresReview, SubStatusNotEvaluated)))
 	// failed still beats notEvaluated
 	assert.Equal(t, makeIS(StatusFailed, SubStatusUnknown), makeIS(CompareStatusAndSubStatus(StatusFailed, StatusSkipped, SubStatusUnknown, SubStatusNotEvaluated)))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@reporthandling/apis/statuses_test.go` around lines 33 - 38, Add tests
asserting that SubStatusNotEvaluated wins over SubStatusIntegration and
SubStatusRequiresReview by extending the existing assertions around
CompareStatusAndSubStatus and makeIS: add two assertions similar to the existing
ones that call CompareStatusAndSubStatus(StatusSkipped, StatusSkipped,
SubStatusNotEvaluated, SubStatusIntegration) and
CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusNotEvaluated,
SubStatusRequiresReview) and expect makeIS(StatusSkipped,
SubStatusNotEvaluated). Also add cross-order checks (e.g.,
CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusIntegration,
SubStatusNotEvaluated)) to ensure precedence is symmetric.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@reporthandling/results/v1/reportsummary/controlsummarymethods.go`:
- Around line 65-78: In the apis.StatusSkipped branch (case apis.StatusSkipped)
the precedence and coverage for skipped substatuses diverges from
CompareStatusAndSubStatus: add a branch to handle apis.SubStatusIntegration (set
controlSummary.StatusInfo.SubStatus = apis.SubStatusIntegration and InnerInfo =
string(apis.SubStatusIntegrationInfo)) and reorder the checks so
apis.SubStatusRequiresReview is evaluated before apis.SubStatusManualReview to
match CompareStatusAndSubStatus; keep comparisons against both the local
subStatus variable and controlSummary.StatusInfo.SubStatus and update InnerInfo
values for each substatus accordingly.

---

Nitpick comments:
In `@reporthandling/apis/statuses_test.go`:
- Around line 33-38: Add tests asserting that SubStatusNotEvaluated wins over
SubStatusIntegration and SubStatusRequiresReview by extending the existing
assertions around CompareStatusAndSubStatus and makeIS: add two assertions
similar to the existing ones that call CompareStatusAndSubStatus(StatusSkipped,
StatusSkipped, SubStatusNotEvaluated, SubStatusIntegration) and
CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusNotEvaluated,
SubStatusRequiresReview) and expect makeIS(StatusSkipped,
SubStatusNotEvaluated). Also add cross-order checks (e.g.,
CompareStatusAndSubStatus(StatusSkipped, StatusSkipped, SubStatusIntegration,
SubStatusNotEvaluated)) to ensure precedence is symmetric.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 699a9ea3-33b0-42a3-9a6f-2f71026c4d71

📥 Commits

Reviewing files that changed from the base of the PR and between 00c8cbe and 9d82ad6.

📒 Files selected for processing (3)
  • reporthandling/apis/statuses.go
  • reporthandling/apis/statuses_test.go
  • reporthandling/results/v1/reportsummary/controlsummarymethods.go

@Sanchit2662
Copy link
Copy Markdown
Contributor Author

Sanchit2662 commented May 6, 2026

Hey @matthyx, kubescape/kubescape#2015 got merged (the part that populates excludedNamespaces / includeNamespaces in scanMetadata). To move forward on the rest of kubescape/kubescape#2010, the next step depends this one. Could you please take a look at this.

Copy link
Copy Markdown
Contributor

@matthyx matthyx left a comment

Choose a reason for hiding this comment

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

I found one blocker.

ResourceAssociatedControl.SetStatus() in reporthandling/results/v1/resourcesresults/controls.go can still overwrite an already-aggregated skipped/notEvaluated result with skipped/configuration when actionRequired == configuration and configs are missing. That contradicts the new precedence in CompareStatusAndSubStatus and can hide the RBAC/API/GVR collection gap this PR is trying to preserve.

Please preserve SubStatusNotEvaluated when it is already present in this path, and add a regression test for it.

Signed-off-by: Sanchit2662 <sanchit2662@gmail.com>
@Sanchit2662 Sanchit2662 requested a review from matthyx May 7, 2026 07:52
Copy link
Copy Markdown
Contributor

@matthyx matthyx left a comment

Choose a reason for hiding this comment

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

Re-checked after the follow-up commit.

The previous blocker in reporthandling/results/v1/resourcesresults/controls.go is fixed: SubStatusNotEvaluated is no longer overwritten by the configuration fallback, and the new regression test covers that path.

I still see the older reporthandling/results/v1/reportsummary/controlsummarymethods.go precedence divergence around integration / requires review / manual review, but that looks pre-existing and non-blocking for this PR.

@matthyx matthyx merged commit 80607ca into kubescape:main May 7, 2026
6 checks passed
@matthyx matthyx moved this to To Archive in KS PRs tracking May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants