Skip to content

🐛 fixes issue when we update the clustermanager with new labels. #1047

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

suvaanshkumar
Copy link
Contributor

@suvaanshkumar suvaanshkumar commented Jun 19, 2025

Summary

This PR removes the3 additional tags in the label selectors of deployments that are created by clustermanager operator in open-cluster-management-hub namespace.

Related issue(s)

Fixes #1046

Summary by CodeRabbit

  • Refactor

    • Deployment manifests now use dynamic label values based on the cluster manager name for improved flexibility.
    • Selector matchLabels in several manifests were simplified to only include the fixed app label, removing conditional dynamic labels.
  • Tests

    • Updated integration tests to align with new label expectations and improved label verification logic.
  • Chores

    • Added a utility function for checking if one set of labels is a subset of another, enhancing test reliability.

@openshift-ci openshift-ci bot requested review from ldpliu and xuezhaojun June 19, 2025 20:58
Copy link
Contributor

openshift-ci bot commented Jun 19, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: suvaanshkumar
Once this PR has been reviewed and has the lgtm label, please assign deads2k for approval. For more information see the Code Review Process.

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

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

Copy link

codecov bot commented Jun 19, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 63.98%. Comparing base (a5757b4) to head (557eda3).
Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1047   +/-   ##
=======================================
  Coverage   63.98%   63.98%           
=======================================
  Files         198      198           
  Lines       19631    19631           
=======================================
  Hits        12561    12561           
  Misses       6020     6020           
  Partials     1050     1050           
Flag Coverage Δ
unit 63.98% <ø> (ø)

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:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@suvaanshkumar suvaanshkumar changed the title 🐛 issue #1045 🐛 fixes issue when we update the clustermanager with new labels. Jun 19, 2025
@openshift-merge-robot
Copy link
Contributor

PR needs rebase.

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.

Copy link

coderabbitai bot commented Jun 27, 2025

Walkthrough

This change updates several cluster manager deployment manifests to use dynamic label values based on the cluster manager name and removes dynamic user-provided labels from deployment selectors to address immutability issues. Test utilities and integration tests were also updated to align with the new label logic.

Changes

File(s) Change Summary
manifests/cluster-manager/management/cluster-manager-addon-manager-deployment.yaml,
manifests/cluster-manager/management/cluster-manager-placement-deployment.yaml,
manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml
Replaced hardcoded label values with dynamic expressions using .ClusterManagerName in metadata and selectors.
manifests/cluster-manager/management/cluster-manager-manifestworkreplicaset-deployment.yaml,
manifests/cluster-manager/management/cluster-manager-registration-webhook-deployment.yaml,
manifests/cluster-manager/management/cluster-manager-work-webhook-deployment.yaml
Removed conditional inclusion of additional labels from deployment selector matchLabels.
test/integration/operator/clustermanager_test.go Updated label validation logic to use a new utility for subset checks and adjusted expected label sets.
test/integration/util/helpers.go Added MapConsists utility function to check if one map is a subset of another.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ClusterManager Template Engine
    participant Kubernetes API Server

    User->>ClusterManager Template Engine: Deploy ClusterManager with custom labels
    ClusterManager Template Engine->>Kubernetes API Server: Create/Update Deployment with selector.matchLabels (only fixed labels, no user labels)
    Kubernetes API Server-->>ClusterManager Template Engine: Deployment created/updated (no immutable selector error)
    User->>Kubernetes API Server: Update Deployment labels (metadata.labels, not selector)
    Kubernetes API Server-->>User: Labels updated successfully
Loading

Assessment against linked issues

Objective Addressed Explanation
Remove user-defined labels from deployment spec.selector to prevent immutability errors (#1046)
Use dynamic label values based on cluster manager name for deployments and selectors (#1046)
Update tests to verify correct label synchronization and reserved label handling (#1046)
Add utility to check label subsets for testing purposes (#1046)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes found.

Possibly related PRs

  • open-cluster-management-io/ocm#1046: Both PRs address label immutability in cluster-manager deployment manifests by using dynamic label values and removing user-defined labels from selectors.

Suggested labels

lgtm, approved

Suggested reviewers

  • suvaanshkumar
  • qiujian16
  • jeffw17

Poem

A cluster hop, a label swap,
No more selector traps to stop!
Dynamic names now fill the air,
With tests to show the labels care.
The bunny cheers with every run—
Immutability woes are done!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 2

🔭 Outside diff range comments (3)
manifests/cluster-manager/management/cluster-manager-addon-manager-deployment.yaml (1)

40-40: Update pod affinity rules to use dynamic values.

The pod affinity rules still reference the hardcoded value "clustermanager-addon-manager-controller" instead of using the dynamic template. This creates inconsistency with the updated labels.

                  values:
-                  - clustermanager-addon-manager-controller
+                  - {{ .ClusterManagerName }}-addon-manager-controller

Apply the same change to both pod affinity rules (lines 40 and 49).

Also applies to: 49-49

manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml (1)

40-40: Update pod affinity rules to use dynamic values.

The pod affinity rules still reference the hardcoded value "clustermanager-registration-controller" instead of using the dynamic template, creating inconsistency.

                  values:
-                  - clustermanager-registration-controller
+                  - {{ .ClusterManagerName }}-registration-controller

Apply this change to both pod affinity rules.

Also applies to: 49-49

manifests/cluster-manager/management/cluster-manager-placement-deployment.yaml (1)

41-41: Update pod affinity rules to use dynamic values.

The pod affinity rules still reference the hardcoded value "clustermanager-placement-controller" instead of using the dynamic template.

                  values:
-                  - clustermanager-placement-controller
+                  - {{ .ClusterManagerName }}-placement-controller

Apply this change to both pod affinity rules.

Also applies to: 50-50

🧹 Nitpick comments (1)
test/integration/util/helpers.go (1)

3-4: Consider improving the function name and documentation.

The function name MapConsists is grammatically awkward. Consider renaming it to MapContains, IsSubsetOf, or MapIsSubsetOf for better clarity.

-// MapConsists checks if the initialMap is a subset of the entireMap.
-func MapConsists(initialMap, entireMap map[string]string) bool {
+// MapContains checks if the entireMap contains all key-value pairs from the initialMap.
+func MapContains(entireMap, initialMap map[string]string) bool {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a5757b4 and 557eda3.

📒 Files selected for processing (8)
  • manifests/cluster-manager/management/cluster-manager-addon-manager-deployment.yaml (2 hunks)
  • manifests/cluster-manager/management/cluster-manager-manifestworkreplicaset-deployment.yaml (0 hunks)
  • manifests/cluster-manager/management/cluster-manager-placement-deployment.yaml (2 hunks)
  • manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml (2 hunks)
  • manifests/cluster-manager/management/cluster-manager-registration-webhook-deployment.yaml (0 hunks)
  • manifests/cluster-manager/management/cluster-manager-work-webhook-deployment.yaml (0 hunks)
  • test/integration/operator/clustermanager_test.go (3 hunks)
  • test/integration/util/helpers.go (1 hunks)
💤 Files with no reviewable changes (3)
  • manifests/cluster-manager/management/cluster-manager-registration-webhook-deployment.yaml
  • manifests/cluster-manager/management/cluster-manager-manifestworkreplicaset-deployment.yaml
  • manifests/cluster-manager/management/cluster-manager-work-webhook-deployment.yaml
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrole.yaml:5-10
Timestamp: 2025-06-26T00:34:09.778Z
Learning: The open-cluster-management-io/ocm codebase uses Go templates (text/template), not Helm templates. The standard pattern for dynamic labels in manifests is: `{{ if gt (len .Labels) 0 }}{{ range $key, $value := .Labels }}"{{ $key }}": "{{ $value }}"{{ end }}{{ end }}`. Do not suggest Helm-specific functions like `toYaml` for this codebase.
manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml (2)
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrole.yaml:5-10
Timestamp: 2025-06-26T00:34:09.778Z
Learning: The open-cluster-management-io/ocm codebase uses Go templates (text/template), not Helm templates. The standard pattern for dynamic labels in manifests is: `{{ if gt (len .Labels) 0 }}{{ range $key, $value := .Labels }}"{{ $key }}": "{{ $value }}"{{ end }}{{ end }}`. Do not suggest Helm-specific functions like `toYaml` for this codebase.
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrolebinding.yaml:5-10
Timestamp: 2025-06-26T00:33:09.303Z
Learning: The OCM (Open Cluster Management) project uses Go templates for Kubernetes manifest generation, not Helm templates. Functions like `toYaml` that are available in Helm are not available in Go templates. The correct Go template syntax for iterating over labels is `{{ range $key, $value := .Labels }}` followed by `"{{ $key }}": "{{ $value }}"`.
manifests/cluster-manager/management/cluster-manager-addon-manager-deployment.yaml (2)
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrole.yaml:5-10
Timestamp: 2025-06-26T00:34:09.778Z
Learning: The open-cluster-management-io/ocm codebase uses Go templates (text/template), not Helm templates. The standard pattern for dynamic labels in manifests is: `{{ if gt (len .Labels) 0 }}{{ range $key, $value := .Labels }}"{{ $key }}": "{{ $value }}"{{ end }}{{ end }}`. Do not suggest Helm-specific functions like `toYaml` for this codebase.
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrolebinding.yaml:5-10
Timestamp: 2025-06-26T00:33:09.303Z
Learning: The OCM (Open Cluster Management) project uses Go templates for Kubernetes manifest generation, not Helm templates. Functions like `toYaml` that are available in Helm are not available in Go templates. The correct Go template syntax for iterating over labels is `{{ range $key, $value := .Labels }}` followed by `"{{ $key }}": "{{ $value }}"`.
manifests/cluster-manager/management/cluster-manager-placement-deployment.yaml (2)
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrole.yaml:5-10
Timestamp: 2025-06-26T00:34:09.778Z
Learning: The open-cluster-management-io/ocm codebase uses Go templates (text/template), not Helm templates. The standard pattern for dynamic labels in manifests is: `{{ if gt (len .Labels) 0 }}{{ range $key, $value := .Labels }}"{{ $key }}": "{{ $value }}"{{ end }}{{ end }}`. Do not suggest Helm-specific functions like `toYaml` for this codebase.
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrolebinding.yaml:5-10
Timestamp: 2025-06-26T00:33:09.303Z
Learning: The OCM (Open Cluster Management) project uses Go templates for Kubernetes manifest generation, not Helm templates. Functions like `toYaml` that are available in Helm are not available in Go templates. The correct Go template syntax for iterating over labels is `{{ range $key, $value := .Labels }}` followed by `"{{ $key }}": "{{ $value }}"`.
test/integration/operator/clustermanager_test.go (2)
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrole.yaml:5-10
Timestamp: 2025-06-26T00:34:09.778Z
Learning: The open-cluster-management-io/ocm codebase uses Go templates (text/template), not Helm templates. The standard pattern for dynamic labels in manifests is: `{{ if gt (len .Labels) 0 }}{{ range $key, $value := .Labels }}"{{ $key }}": "{{ $value }}"{{ end }}{{ end }}`. Do not suggest Helm-specific functions like `toYaml` for this codebase.
Learnt from: zhiweiyin318
PR: open-cluster-management-io/ocm#1046
File: manifests/cluster-manager/hub/cluster-manager-clusterprofiles-clusterrolebinding.yaml:5-10
Timestamp: 2025-06-26T00:33:09.303Z
Learning: The OCM (Open Cluster Management) project uses Go templates for Kubernetes manifest generation, not Helm templates. Functions like `toYaml` that are available in Helm are not available in Go templates. The correct Go template syntax for iterating over labels is `{{ range $key, $value := .Labels }}` followed by `"{{ $key }}": "{{ $value }}"`.
🧬 Code Graph Analysis (1)
test/integration/operator/clustermanager_test.go (2)
test/integration/util/helpers.go (1)
  • MapConsists (4-17)
vendor/github.com/onsi/gomega/matchers.go (1)
  • BeNil (51-53)
🔇 Additional comments (5)
manifests/cluster-manager/management/cluster-manager-addon-manager-deployment.yaml (1)

7-7: LGTM! Dynamic label templating is correctly applied.

The replacement of hardcoded label values with {{ .ClusterManagerName }}-addon-manager-controller properly implements dynamic labeling based on the cluster manager name.

Also applies to: 18-18, 22-22

manifests/cluster-manager/management/cluster-manager-registration-deployment.yaml (1)

7-7: LGTM! Dynamic label templating is correctly applied.

The replacement of hardcoded label values with {{ .ClusterManagerName }}-registration-controller properly implements dynamic labeling.

Also applies to: 18-18, 22-22

manifests/cluster-manager/management/cluster-manager-placement-deployment.yaml (1)

7-7: LGTM! Dynamic label templating is correctly applied.

The replacement of hardcoded label values with {{ .ClusterManagerName }}-placement-controller properly implements dynamic labeling.

Also applies to: 18-18, 23-23

test/integration/operator/clustermanager_test.go (2)

1186-1186: Consider removing the generic "app": "clustermanager" label.

The removal of the generic "app": "clustermanager" label from the expected labels map aligns with the shift to more specific, dynamic labeling using cluster manager names.


1234-1234: LGTM! Improved variable naming for clarity.

The updated variable names like k8sHubWorkWebhookDeployment, k8sHubPlacementDeployment, etc., make the test more readable and less confusing than reusing generic names.

Also applies to: 1244-1244, 1254-1254, 1264-1264

// MapConsists checks if the initialMap is a subset of the entireMap.
func MapConsists(initialMap, entireMap map[string]string) bool {
if len(initialMap) == 0 {
println("Initial map is empty, returning true")
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove debug print statements from library code.

The println statements are inappropriate for library/utility code as they produce unwanted output during testing and production use. Consider using a proper logging framework or removing them entirely.

 	if len(initialMap) == 0 {
-		println("Initial map is empty, returning true")
 		return true
 	}
 	for key, value := range initialMap {
 		if entireMap[key] != value {
-			println("Map does not consist, returning false")
 			return false
 		}
 	}
-	println("Map consists of the required values, returning true")
 	return true

Also applies to: 11-11, 15-15

🤖 Prompt for AI Agents
In test/integration/util/helpers.go at lines 6, 11, and 15, remove the println
debug statements as they produce unwanted output in tests and production.
Replace them with proper logging calls if necessary, or remove them entirely to
keep the utility code clean and silent during normal operation.

return fmt.Errorf("expected registration-controller labels to be %v, but got %v", labels, registrationDeployment.GetLabels())
}
registrationLabels := registrationDeployment.GetLabels()
util.MapConsists(registrationLabels, labels)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix MapConsists usage - missing assertions.

The util.MapConsists calls are not being used properly for testing. The function returns a boolean, but you're not asserting on the result. This means the test will pass even if the label subset check fails.

-				util.MapConsists(registrationLabels, labels)
+				if !util.MapConsists(labels, registrationLabels) {
+					return fmt.Errorf("expected labels not found in deployment labels")
+				}

Apply similar fixes to all MapConsists calls in this test. Note that I've also swapped the parameter order based on the function's expected behavior (initialMap should be the expected labels, entireMap should be the actual deployment labels).

Also applies to: 1228-1228, 1238-1238, 1248-1248, 1258-1258, 1269-1269

🤖 Prompt for AI Agents
In test/integration/operator/clustermanager_test.go at line 1206 and similarly
at lines 1228, 1238, 1248, 1258, and 1269, the calls to util.MapConsists are
missing assertions on their boolean results, causing tests to pass regardless of
the check outcome. Fix this by wrapping each util.MapConsists call in an
assertion function (e.g., require.True or assert.True) to verify the result is
true. Also, ensure the parameter order matches the function's expected behavior,
passing the expected labels as the first argument and the actual deployment
labels as the second.

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.

2 participants