Skip to content

fix(customresourcestate): do not write GVK labels into the shared config - #3077

Open
mrueg wants to merge 2 commits into
kubernetes:mainfrom
mrueg:harden-crs-commonlabels
Open

fix(customresourcestate): do not write GVK labels into the shared config#3077
mrueg wants to merge 2 commits into
kubernetes:mainfrom
mrueg:harden-crs-commonlabels

Conversation

@mrueg

@mrueg mrueg commented Aug 10, 2026

Copy link
Copy Markdown
Member

What this PR does / why we need it:

compile takes Resource by value, but CommonLabels is a map, so the copy shares it with the configured resource and with every other copy made from it — and wildcard resolution produces one copy per discovered GVK:

if resource.CommonLabels == nil {
	resource.CommonLabels = map[string]string{}
}
resource.CommonLabels[customResourceState+"_group"] = resource.GroupVersionKind.Group
resource.CommonLabels[customResourceState+"_version"] = resource.GroupVersionKind.Version
resource.CommonLabels[customResourceState+"_kind"] = resource.GroupVersionKind.Kind

Those three writes go into a map every copy points at, and into the user's configuration. Compiling myteam.io/v1 Foo and then myteam.io/v2 Bar from one configured resource leaves the caller's map as:

expected: map[string]string{"team":"myteam"}
actual:   map[string]string{"customresource_group":"myteam.io",
                            "customresource_kind":"Bar",
                            "customresource_version":"v2",
                            "team":"myteam"}

To be clear about severity: the emitted metrics are correct today. Each compile overwrites all three keys before Merge copies them into the family, and factories are built one at a time, so no family ends up with another GVK's labels. This is a hazard rather than a live bug — but it is one concurrent or partially-overwriting compile away from being one, and mutating configuration the caller owns is wrong regardless.

Building a new map removes the sharing. The test asserts both that each resolution keeps its own GVK labels and that the configured map is left as the user wrote it; the second assertion fails on main with the output above.

How does this change affect the cardinality of KSM: does not change cardinality

Which issue(s) this PR fixes: N/A

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue where resources resolved from wildcards could share or overwrite labels.
    • Common labels now remain unchanged when resource-specific labels are added.
    • Resources with different group, version, and kind values retain independent labels, improving label accuracy and consistency.
  • Tests

    • Added regression coverage for label isolation and preservation of configured common labels.

compile takes Resource by value, but CommonLabels is a map, so it is
shared with the configured resource and with every copy made from it.
Wildcard resolution makes one copy per discovered GVK, so writing the
GVK labels in place mutates a map they all point at, and leaks them back
into the user's configuration:

    expected: map[string]string{"team":"myteam"}
    actual:   map[string]string{"customresource_group":"myteam.io",
                                "customresource_kind":"Bar",
                                "customresource_version":"v2",
                                "team":"myteam"}

The emitted metrics are correct today, because each compile overwrites
all three keys before Merge copies them into the family, and factories
are built one at a time. That makes this a hazard rather than a live
bug -- but it is one concurrent or partial compile away from families
carrying another GVK's labels.

Build a new map instead of writing through the shared one.
@kubernetes-prow
kubernetes-prow Bot requested review from bhope and nmn3m August 10, 2026 22:26
@kubernetes-prow kubernetes-prow Bot added the needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. label Aug 10, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

This issue is currently awaiting triage.

If kube-state-metrics contributors determine this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@kubernetes-prow kubernetes-prow Bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 10, 2026
@github-project-automation github-project-automation Bot moved this to Needs Triage in SIG Instrumentation Aug 10, 2026
@kubernetes-prow kubernetes-prow Bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7a04355f-2a96-4026-937d-74da09747497

📥 Commits

Reviewing files that changed from the base of the PR and between 2c16de5 and 54778db.

📒 Files selected for processing (1)
  • pkg/customresourcestate/registry_factory_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/customresourcestate/registry_factory_test.go

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


📝 Walkthrough

Walkthrough

The compile path copies CommonLabels before adding group, version, and kind labels. A regression test verifies that compiled resources use independent label maps and that the configured labels remain unchanged.

Changes

Common-label isolation

Layer / File(s) Summary
Copy labels before GVK enrichment
pkg/customresourcestate/registry_factory.go, pkg/customresourcestate/registry_factory_test.go
compile copies CommonLabels before adding GVK labels. The regression test verifies independent resource maps and unchanged configured labels.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 54778

The change prevents GVK labels from mutating shared configuration while preserving per-resource labels; no actionable merge-blocking risk remains beyond normal checks.

Suggested reviewers: nmn3m

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: preventing GVK labels from modifying the shared custom resource configuration.
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 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.

@bhope bhope left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm
/hold

Feel free to unhold.

return out
}

// Wildcard resolution produces one Resource copy per discovered GVK, all sharing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We probably may not need them in the tests. WDYT?

@kubernetes-prow kubernetes-prow Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 15, 2026
@kubernetes-prow kubernetes-prow Bot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 15, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bhope, mrueg

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Keep a two-line note on why the shared map matters and drop the inline
comments that restated the assertions.

Addresses review feedback on kubernetes#3077.
@kubernetes-prow

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@kubernetes-prow kubernetes-prow Bot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

2 participants