Skip to content

ROX-36158: track deployment managing resource - #22102

Draft
Stringy wants to merge 1 commit into
masterfrom
giles/ROX-36158-track-deployment-managing-resource
Draft

ROX-36158: track deployment managing resource#22102
Stringy wants to merge 1 commit into
masterfrom
giles/ROX-36158-track-deployment-managing-resource

Conversation

@Stringy

@Stringy Stringy commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Description

change me!

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

change me!

@openshift-ci

openshift-ci Bot commented Aug 5, 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 Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Deployments can now include managing resource details when they are owned by another Kubernetes resource.
    • Added support for capturing owner metadata such as kind, API group, version, name, and UID.
  • Bug Fixes

    • Improved handling of deployment conversion so native Kubernetes owners and standalone resources are treated correctly.
    • Suppresses subordinate replica sets from being surfaced as managed deployments.
  • Tests

    • Added coverage for API version parsing, owner reference selection, and deployment conversion with native and custom resource ownership.

Walkthrough

The change adds a ManagingResource protobuf message and populates deployment metadata from eligible non-native Kubernetes controller owner references. Tests cover API-version parsing, owner selection, deployment conversion, and native-resource suppression.

Changes

Managing resource tracking

Layer / File(s) Summary
Managing resource storage contract
proto/storage/deployment.proto
Adds ManagingResource and stores it on Deployment.managing_resource at field tag 36.
Owner-reference conversion
pkg/protoconv/resources/resources.go
Selects eligible non-native controller owners, parses their API group and version, and assigns the result during deployment conversion.
Conversion behavior validation
pkg/protoconv/resources/resources_test.go, sensor/kubernetes/listener/resources/convert_test.go
Tests API-version parsing, owner precedence, CRD metadata propagation, ownerless deployments, and native-resource suppression.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: ajheflin, guzalv

Sequence Diagram(s)

sequenceDiagram
  participant StaticResource
  participant ResourceConverter
  participant OwnerReferenceSelector
  participant Deployment
  StaticResource->>ResourceConverter: owner references
  ResourceConverter->>OwnerReferenceSelector: select managing owner
  OwnerReferenceSelector->>Deployment: ManagingResource metadata
  ResourceConverter->>Deployment: converted deployment
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description retains placeholder text and does not explain the implementation, testing, or validation steps. Replace the placeholder text with implementation details, test coverage, validation steps, and the applicable documentation and quality checklist selections.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: tracking the deployment managing resource.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ 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 giles/ROX-36158-track-deployment-managing-resource

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
proto/storage/deployment.proto (1)

66-70: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Align the field comment with the actual behavior.

The comment states the field is populated when the owner chain includes a CRD controller "(or in addition to)" native types. NewDeploymentFromStaticResource returns nil, nil when any tracked native owner reference exists. In that case no deployment record is produced at all, so the "in addition to" case never reaches this field.

📝 Proposed comment change
   // Non-native (CRD) resource that manages this deployment. Populated when
-  // a deployment's OwnerReference chain includes a CRD controller rather than
-  // (or in addition to) native Kubernetes resource types.
+  // the top-level deployment's controller OwnerReference points to a CRD
+  // rather than a native Kubernetes resource type. Resources owned by a
+  // tracked native resource are not reported as deployments at all.
   ManagingResource managing_resource = 36;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proto/storage/deployment.proto` around lines 66 - 70, Update the comment for
ManagingResource.managing_resource to state that it is populated only when the
deployment’s OwnerReference chain includes a CRD controller and no tracked
native owner reference causes the deployment to be discarded; remove the
misleading “or in addition to” wording.
pkg/protoconv/resources/resources_test.go (1)

362-367: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use protoassert.Equal to compare protobuf messages.

tc.expected and result are *storage.ManagingResource. The assert.Equal function falls back to reflect.DeepEqual, which inspects unexported fields (state protoimpl.MessageState, sizeCache, unknownFields) in the generated struct. These internal fields are not part of the message contract and can differ after the protobuf runtime populates internal state. protoassert.Equal uses the generated EqualVT method instead, which compares only contract-defined fields and handles nil cases correctly.

Add the import "github.com/stackrox/rox/pkg/protoassert" and replace assert.Equal with protoassert.Equal:

Proposed change
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			result := managingResourceFromOwnerRefs(tc.refs)
-			assert.Equal(t, tc.expected, result)
+			protoassert.Equal(t, tc.expected, result)
 		})
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/protoconv/resources/resources_test.go` around lines 362 - 367, Update the
protobuf comparison in the managingResourceFromOwnerRefs test loop to use
protoassert.Equal instead of assert.Equal, and add the
github.com/stackrox/rox/pkg/protoassert import. Keep the existing test inputs
and expected-result assertions unchanged.
pkg/protoconv/resources/resources.go (1)

107-112: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace strings.LastIndex with schema.ParseGroupVersion for stricter validation.

k8s.io/apimachinery is already a direct dependency. schema.ParseGroupVersion implements the same mapping for valid inputs and rejects malformed values with more than one / instead of accepting them silently. The current implementation returns the substring before the last / as the group for any input with slashes; ParseGroupVersion strictly requires exactly one / for grouped APIs and zero / for core APIs.

On parse error, return the empty group and the input string as version to match the current fallback for core APIs. Remove the strings import since the proposed change eliminates its only use.

♻️ Proposed refactor
-func groupAndVersionFromAPIVersion(apiVersion string) (group, version string) {
-	if i := strings.LastIndex(apiVersion, "/"); i >= 0 {
-		return apiVersion[:i], apiVersion[i+1:]
-	}
-	return "", apiVersion
-}
+func groupAndVersionFromAPIVersion(apiVersion string) (group, version string) {
+	gv, err := schema.ParseGroupVersion(apiVersion)
+	if err != nil {
+		return "", apiVersion
+	}
+	return gv.Group, gv.Version
+}

Import "k8s.io/apimachinery/pkg/runtime/schema" and remove "strings" from the imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/protoconv/resources/resources.go` around lines 107 - 112, Update
groupAndVersionFromAPIVersion to use schema.ParseGroupVersion instead of
strings.LastIndex so only valid core or grouped API versions are accepted. On
parse success, return the parsed Group and Version; on parse error, preserve the
current fallback by returning an empty group and the original apiVersion as the
version. Remove the now-unused strings import and add the schema import, keeping
the behavior anchored to groupAndVersionFromAPIVersion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/protoconv/resources/resources.go`:
- Around line 83-101: Update managingResourceFromOwnerRefs to skip owner
references whose APIVersion is native by applying kubernetes.IsNativeAPI
alongside the existing IsTrackedOwnerReference and controller checks, so only
non-native controller owners produce a ManagingResource. Extend
TestManagingResourceFromOwnerRefs with a native non-deployment owner case and
verify it is ignored.

---

Nitpick comments:
In `@pkg/protoconv/resources/resources_test.go`:
- Around line 362-367: Update the protobuf comparison in the
managingResourceFromOwnerRefs test loop to use protoassert.Equal instead of
assert.Equal, and add the github.com/stackrox/rox/pkg/protoassert import. Keep
the existing test inputs and expected-result assertions unchanged.

In `@pkg/protoconv/resources/resources.go`:
- Around line 107-112: Update groupAndVersionFromAPIVersion to use
schema.ParseGroupVersion instead of strings.LastIndex so only valid core or
grouped API versions are accepted. On parse success, return the parsed Group and
Version; on parse error, preserve the current fallback by returning an empty
group and the original apiVersion as the version. Remove the now-unused strings
import and add the schema import, keeping the behavior anchored to
groupAndVersionFromAPIVersion.

In `@proto/storage/deployment.proto`:
- Around line 66-70: Update the comment for ManagingResource.managing_resource
to state that it is populated only when the deployment’s OwnerReference chain
includes a CRD controller and no tracked native owner reference causes the
deployment to be discarded; remove the misleading “or in addition to” wording.
🪄 Autofix

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: Enterprise

Run ID: ea36a4f5-6311-4b34-90fe-7705f271a72e

📥 Commits

Reviewing files that changed from the base of the PR and between 58834eb and 5d19c19.

⛔ Files ignored due to path filters (6)
  • generated/api/v1/deployment_service.swagger.json is excluded by !**/generated/**
  • generated/api/v1/detection_service.swagger.json is excluded by !**/generated/**
  • generated/api/v1/vuln_mgmt_service.swagger.json is excluded by !**/generated/**
  • generated/storage/deployment.pb.go is excluded by !**/*.pb.go, !**/generated/**
  • generated/storage/deployment_vtproto.pb.go is excluded by !**/*.pb.go, !**/generated/**
  • proto/storage/proto.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • pkg/protoconv/resources/resources.go
  • pkg/protoconv/resources/resources_test.go
  • proto/storage/deployment.proto
  • sensor/kubernetes/listener/resources/convert_test.go

Comment on lines +83 to +101
func managingResourceFromOwnerRefs(refs []metav1.OwnerReference) *storage.ManagingResource {
for _, ref := range refs {
if IsTrackedOwnerReference(ref) {
continue
}
if ref.Controller == nil || !*ref.Controller {
continue
}
group, version := groupAndVersionFromAPIVersion(ref.APIVersion)
return &storage.ManagingResource{
Kind: ref.Kind,
ApiGroup: group,
ApiVersion: version,
Name: ref.Name,
Uid: string(ref.UID),
}
}
return nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add a native-API check. The current filter admits native owners.

The function name, the doc comment, and the ManagingResource proto comment all state that this captures a non-native (CRD) owner. The loop never checks the API group. It only skips references that are tracked, and IsTrackedOwnerReference (Line 58) requires IsDeploymentResource(reference.Kind) && kubernetes.IsNativeAPI(reference.APIVersion).

A native controller owner whose kind is not a deployment resource therefore passes both continue guards. Such an owner is stored as a ManagingResource with an empty or *.k8s.io ApiGroup. Consumers that read this field to identify a custom resource then receive a native Kubernetes object.

Reuse the existing kubernetes.IsNativeAPI helper so one definition of "native" applies in both places.

🐛 Proposed fix
 func managingResourceFromOwnerRefs(refs []metav1.OwnerReference) *storage.ManagingResource {
 	for _, ref := range refs {
-		if IsTrackedOwnerReference(ref) {
+		// Only non-native (CRD) owners are reported as managing resources.
+		if kubernetes.IsNativeAPI(ref.APIVersion) {
 			continue
 		}
 		if ref.Controller == nil || !*ref.Controller {
 			continue
 		}

Add a case to TestManagingResourceFromOwnerRefs for a native, non-deployment owner kind to lock the behavior in.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func managingResourceFromOwnerRefs(refs []metav1.OwnerReference) *storage.ManagingResource {
for _, ref := range refs {
if IsTrackedOwnerReference(ref) {
continue
}
if ref.Controller == nil || !*ref.Controller {
continue
}
group, version := groupAndVersionFromAPIVersion(ref.APIVersion)
return &storage.ManagingResource{
Kind: ref.Kind,
ApiGroup: group,
ApiVersion: version,
Name: ref.Name,
Uid: string(ref.UID),
}
}
return nil
}
func managingResourceFromOwnerRefs(refs []metav1.OwnerReference) *storage.ManagingResource {
for _, ref := range refs {
// Only non-native (CRD) owners are reported as managing resources.
if kubernetes.IsNativeAPI(ref.APIVersion) {
continue
}
if ref.Controller == nil || !*ref.Controller {
continue
}
group, version := groupAndVersionFromAPIVersion(ref.APIVersion)
return &storage.ManagingResource{
Kind: ref.Kind,
ApiGroup: group,
ApiVersion: version,
Name: ref.Name,
Uid: string(ref.UID),
}
}
return nil
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/protoconv/resources/resources.go` around lines 83 - 101, Update
managingResourceFromOwnerRefs to skip owner references whose APIVersion is
native by applying kubernetes.IsNativeAPI alongside the existing
IsTrackedOwnerReference and controller checks, so only non-native controller
owners produce a ManagingResource. Extend TestManagingResourceFromOwnerRefs with
a native non-deployment owner case and verify it is ignored.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🚀 Build Images Ready

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

export MAIN_IMAGE_TAG=4.12.x-675-g5d19c19e05

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 51.24%. Comparing base (71326b7) to head (5d19c19).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #22102      +/-   ##
==========================================
- Coverage   51.27%   51.24%   -0.04%     
==========================================
  Files        2869     2869              
  Lines      179349   179368      +19     
==========================================
- Hits        91965    91911      -54     
- Misses      79325    79379      +54     
- Partials     8059     8078      +19     
Flag Coverage Δ
go-unit-tests 51.24% <100.00%> (-0.04%) ⬇️

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.

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