Skip to content

Conversation

@zhiweiyin318
Copy link
Member

@zhiweiyin318 zhiweiyin318 commented Nov 13, 2025

Summary

support to create a loadBalancer service for grpc server.

Related issue(s)

#1250
Fixes #

Summary by CodeRabbit

  • New Features

    • CRD and manifests now support LoadBalancer and Route endpoint types for GRPC and HTTPS (host + caBundle variants).
    • GRPC service will use port 443 and LoadBalancer type when configured; otherwise remains ClusterIP on port 8090.
    • Endpoint-type selection for GRPC is exposed for resolution.
  • Bug Fixes

    • Certificate rotation resolves GRPC hostnames (including LoadBalancer ingress) and aggregates resolution errors.
  • Tests

    • Added tests for LoadBalancer/Route exposures, service type/port behavior, hostname resolution, and certificate rotation.
  • Chores

    • API dependency version updated.

@coderabbitai
Copy link

coderabbitai bot commented Nov 13, 2025

Walkthrough

Adds loadBalancer and route endpoint exposure variants to ClusterManager CRDs/OLM manifests, updates manifests and Hub config to support loadBalancer gRPC services, extends helper logic to resolve LoadBalancer ingress via Kubernetes API, adjusts cert-rotation to aggregate hostname-resolution errors, and bumps an API dependency.

Changes

Cohort / File(s) Summary
CRD & OpenAPI manifests
deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml, deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml, deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
Extend CRD/OpenAPI schema to add loadBalancer and route object variants (with caBundle and host) under spec.serverConfiguration.endpointsExposure for grpc.hostname and https.hostname; update type enums to include loadBalancer and route.
OLM CSV metadata
deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
Updated metadata.createdAt timestamp.
Go dependency
go.mod
Bumped open-cluster-management.io/api module version.
Service manifest template
manifests/cluster-manager/hub/grpc-server/service.yaml
Make Service port and type conditional on GRPCEndpointType: use port 443 and LoadBalancer for loadBalancer, otherwise port 8090 and ClusterIP.
Hub config model
manifests/config.go
Added GRPCEndpointType string field to HubConfig.
Helpers logic
pkg/operator/helpers/helpers.go
Changed GRPCServerHostNames signature to accept kubernetes.Interface and return ([]string, error); added handling for loadBalancer endpoints by querying Service/Ingress and appending resolved hostnames; added GRPCServerEndpointType(cm *operatorapiv1.ClusterManager) string.
Helper tests
pkg/operator/helpers/helpers_test.go
Refactored tests to use ServerConfiguration.EndpointsExposure, introduced fake kube client seeding, covered hostname/loadBalancer variants and error cases, and added tests for GRPCServerEndpointType.
Cert-rotation controller
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go
Switched rotations from slice to map, aggregate hostname-resolution errors, compute hostnames via GRPCServerHostNames, conditionally add/update GRPC target rotations only when resolution succeeds, and return aggregated errors.
Cert-rotation tests
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
Added TestCertRotationGRPCServerHostNames covering loadBalancer/hostname scenarios, error paths, and validating TLS secret contents and rotation hostnames.
ClusterManager controller
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
Populate GRPCEndpointType in Hub config when GRPC auth is enabled; minor comment fix.
ClusterManager controller tests
pkg/operator/operators/clustermanager/controllers/clustermanager_controller_test.go
Added TestGRPCServiceLoadBalancerType to validate Service type and port for different endpoint configurations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Extra attention:
    • pkg/operator/helpers/helpers.go: new kubeClient parameter, Service/Ingress lookup, ingress validation, and error propagation.
    • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go and its tests: map-based rotations, conditional updates, aggregated error handling, and TLS secret validation.
    • Template conditional in manifests/cluster-manager/hub/grpc-server/service.yaml and interplay with GRPCEndpointType.
    • Tests that seed fake Kubernetes objects and assert both success and error paths.

Possibly related PRs

Suggested labels

lgtm, approved

Suggested reviewers

  • dongbeiqing91
  • zhujian7
  • qiujian16

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature: adding support for loadBalancer as a gRPC endpoint type, which aligns with all the changes in the PR.
Description check ✅ Passed The PR description includes a summary section that explains the feature (support for loadBalancer service for gRPC server), but the 'Related issue(s)' section is incomplete with only a template placeholder 'Fixes #' and no actual issue reference.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@codecov
Copy link

codecov bot commented Nov 13, 2025

Codecov Report

❌ Patch coverage is 88.00000% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.20%. Comparing base (ded1e02) to head (da8c83d).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
.../certrotationcontroller/certrotation_controller.go 81.48% 4 Missing and 1 partial ⚠️
pkg/operator/helpers/helpers.go 91.30% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1255      +/-   ##
==========================================
- Coverage   62.21%   62.20%   -0.01%     
==========================================
  Files         209      209              
  Lines       16997    17037      +40     
==========================================
+ Hits        10574    10598      +24     
- Misses       5305     5319      +14     
- Partials     1118     1120       +2     
Flag Coverage Δ
unit 62.20% <88.00%> (-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:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

🧹 Nitpick comments (1)
pkg/operator/helpers/helpers_test.go (1)

1881-2214: Add route coverage to prevent regressions

Once you wire the route host handling, please extend TestGRPCServerHostNames with a EndpointTypeRoute case so we fail fast if that path regresses again.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ded1e02 and 248125b.

⛔ Files ignored due to path filters (5)
  • go.sum is excluded by !**/*.sum
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go is excluded by !vendor/**
📒 Files selected for processing (14)
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml (1 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (2 hunks)
  • go.mod (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/clusterrole.yaml (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/service.yaml (1 hunks)
  • manifests/config.go (1 hunks)
  • pkg/operator/helpers/helpers.go (1 hunks)
  • pkg/operator/helpers/helpers_test.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (4 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📚 Learning: 2025-08-06T06:00:53.508Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: deploy/cluster-manager/config/rbac/cluster_role.yaml:165-168
Timestamp: 2025-08-06T06:00:53.508Z
Learning: In OCM gRPC deployments, both the cluster-manager operator ClusterRole and the gRPC server ClusterRole need "create" permission on "managedclustersets/join" resources for proper bootstrapping of managed clusters.

Applied to files:

  • manifests/cluster-manager/hub/grpc-server/clusterrole.yaml
📚 Learning: 2025-08-04T08:58:41.865Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: manifests/klusterlet/management/klusterlet-registration-deployment.yaml:111-115
Timestamp: 2025-08-04T08:58:41.865Z
Learning: In OCM klusterlet deployments, gRPC authentication uses different file naming conventions than CSR/kube authentication: gRPC auth expects config.yaml files (/spoke/bootstrap/config.yaml and /spoke/hub-kubeconfig/config.yaml) while CSR/kube auth uses kubeconfig files. The gRPC driver explicitly creates config.yaml files in the secret data via additionalSecretData["config.yaml"] = d.configTemplate.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
  • pkg/operator/helpers/helpers.go
  • pkg/operator/helpers/helpers_test.go
📚 Learning: 2025-07-25T01:21:08.891Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1077
File: test/integration/registration/spokecluster_grpc_test.go:0-0
Timestamp: 2025-07-25T01:21:08.891Z
Learning: In OCM integration tests, gRPC and kube authentication mechanisms require different CSR handling approaches: gRPC authentication uses util.ApproveCSR since the hub controller signs client certificates, while kube authentication uses authn.ApproveSpokeClusterCSR to simulate the kube-controller-manager signing client certificates.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
📚 Learning: 2025-09-24T00:18:33.339Z
Learnt from: zhiweiyin318
Repo: open-cluster-management-io/ocm PR: 1194
File: deploy/klusterlet/chart/klusterlet/templates/bootstrap_kubeconfig_secret.yaml:25-27
Timestamp: 2025-09-24T00:18:33.339Z
Learning: gRPC config in OCM klusterlet bootstrap secrets does not support multiHubBootstrapHubKubeConfigs scenarios - it is intentionally designed only for single hub bootstrap configurations.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-08-28T01:59:04.611Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.

Applied to files:

  • go.mod
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:05.882Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:128-135
Timestamp: 2025-08-28T01:58:05.882Z
Learning: Files in deploy/cluster-manager/chart/cluster-manager/crds/ and similar CRD directories are often copied from vendor/upstream sources and should not be modified directly to avoid conflicts during updates.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:37.933Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:247-280
Timestamp: 2025-08-28T01:58:37.933Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor and should not be modified locally as changes may be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:23.958Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:192-225
Timestamp: 2025-08-28T01:58:23.958Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ and deploy/cluster-manager/config/crds/ directories are copied from vendor (open-cluster-management.io/api dependency) and should not be modified locally.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-07-01T05:27:25.998Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1058
File: pkg/server/services/cluster/cluster.go:48-64
Timestamp: 2025-07-01T05:27:25.998Z
Learning: The ClusterService struct in pkg/server/services/cluster/cluster.go implements the server.Service interface, so method names like List() cannot be renamed as they must match the interface definition exactly.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-08-28T04:09:12.357Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:94-176
Timestamp: 2025-08-28T04:09:12.357Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor/upstream sources and should not be modified directly.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:50.021Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:168-175
Timestamp: 2025-08-28T01:58:50.021Z
Learning: In the OCM project, CRD schemas come from the open-cluster-management.io/api dependency. Changes to CRD schemas should be made upstream in that API package, not in the local CRD YAML files which are generated/copied from the API types.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-09-16T03:04:38.251Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:48-48
Timestamp: 2025-09-16T03:04:38.251Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are properly updated via "make update" when vendor dependencies change (like open-cluster-management.io/api updates) and validated by "make verify". The issue is only with local hand-edits, not legitimate vendor update processes.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-10-10T02:50:14.188Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1204
File: manifests/cluster-manager/hub/crds/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml:88-91
Timestamp: 2025-10-10T02:50:14.188Z
Learning: Kubernetes CustomResourceDefinition (CRD) OpenAPI v3 schema does not support the `deprecated: true` property for individual fields. Field-level deprecation must be documented in the description field only. The formal `deprecated` property is not supported by Kubernetes CRD tooling.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
🧬 Code graph analysis (5)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerEndpointType (983-998)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (2)
pkg/operator/helpers/queuekey.go (1)
  • ClusterManagerNamespace (51-56)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (2)
pkg/operator/helpers/queuekey.go (6)
  • GRPCServerSecret (48-48)
  • ClusterManagerNamespace (51-56)
  • SignerSecret (45-45)
  • RegistrationWebhookSecret (40-40)
  • WorkWebhookSecret (42-42)
  • CaBundleConfigmap (46-46)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (2)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerHostNames (935-981)
pkg/operator/helpers/queuekey.go (1)
  • GRPCServerSecret (48-48)
pkg/operator/helpers/helpers_test.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCServerHostNames (935-981)
  • GRPCServerEndpointType (983-998)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: e2e
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e-hosted
  • GitHub Check: build
  • GitHub Check: verify
  • GitHub Check: integration
  • GitHub Check: unit
🔇 Additional comments (1)
manifests/cluster-manager/hub/grpc-server/clusterrole.yaml (1)

18-20: Verify that replicasets access is required for loadBalancer endpoint discovery.

The new RBAC rule grants get on replicasets in the apps API group, which follows the existing pattern and appears syntactically sound. However, clarification on its necessity would strengthen the review.

Please confirm:

  1. Why the gRPC server needs to query replicasets when resolving LoadBalancer endpoints. Is this for pod topology discovery, health checks, or another aspect of endpoint resolution?
  2. Whether get is the minimal verb needed, or if additional verbs (list, watch) are required during operation.
  3. Whether any other RBAC changes are needed in other ClusterRoles or related manifests to fully support the loadBalancer feature.

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

♻️ Duplicate comments (1)
pkg/operator/helpers/helpers.go (1)

976-978: Route endpoint type remains unimplemented.

The route case still only contains a TODO comment without appending the route host to the SAN list. When users configure endpoint.GRPC.Type = route, the TLS certificate won't include the route hostname, causing handshake failures.

Apply this diff to handle the route case:

 		case operatorapiv1.EndpointTypeRoute:
-			// TODO: append route.host to the hostName
+			if endpoint.GRPC.Route != nil && strings.TrimSpace(endpoint.GRPC.Route.Host) != "" {
+				hostNames = append(hostNames, endpoint.GRPC.Route.Host)
+			}
🧹 Nitpick comments (3)
deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (1)

569-611: CRD schema changes look structurally correct; verify they are vendor-synced

The additions of loadBalancer and route under both grpc and https (with caBundle and host fields) and the extension of the type enum to include loadBalancer and route are structurally consistent with the existing hostname block and with how the code uses these endpoint types.

However, per prior project notes, CRDs under deploy/cluster-manager/config/crds/ are typically copied/generated from the upstream open-cluster-management.io/api types and not edited manually, otherwise they can be overwritten or drift from the source. Please confirm these changes came from updating/regenerating the API dependency (and that the chart/OLM copies are in sync), rather than hand-editing this file.

Based on learnings

Also applies to: 616-620, 628-683, 676-679

deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (1)

569-611: Ensure OLM CRD manifest remains in sync with upstream-generated schema

The loadBalancer/route additions and enum updates here mirror the main CRD schema and look consistent. Given this OLM manifest is normally generated/copied from upstream (and can be overwritten on vendor bumps), please confirm it was updated via the same generation/sync process as the main CRD and not manually edited, so we avoid schema drift between operator, chart CRDs, and OLM metadata.

Based on learnings

Also applies to: 616-620, 628-683, 676-679

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)

362-716: Comprehensive GRPC hostname rotation tests; consider also asserting success cases return no error

TestCertRotationGRPCServerHostNames gives solid coverage of GRPC hostname handling for:

  • LoadBalancer endpoints with IP vs hostname.
  • Hostname endpoints with custom host.
  • Error cases where the service is missing or has no ingress.

Checking rotationMap for the GRPC rotation and verifying the hostnames slice matches expectations is exactly what we need.

One small robustness improvement: in success cases (expectedErrorSubstr == ""), the test currently ignores the err returned from controller.sync. If future changes cause sync to start returning a non-nil error while still partially populating rotationMap, these tests might still pass. You could tighten the contract by explicitly asserting err == nil for those cases, e.g.:

-			// Sync the controller
-			err := controller.sync(context.TODO(), syncContext)
-
-			// Check if we expect an error
-			if c.expectedErrorSubstr != "" {
+			// Sync the controller
+			err := controller.sync(context.TODO(), syncContext)
+
+			// Check if we expect an error
+			if c.expectedErrorSubstr != "" {
 				...
-			}
+			} else if err != nil {
+				t.Fatalf("expected no error, got: %v", err)
+			}

Otherwise, the structure and coverage of the test look good.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 248125b and 7b665af.

⛔ Files ignored due to path filters (5)
  • go.sum is excluded by !**/*.sum
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go is excluded by !vendor/**
📒 Files selected for processing (14)
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml (1 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (2 hunks)
  • go.mod (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/clusterrole.yaml (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/service.yaml (1 hunks)
  • manifests/config.go (1 hunks)
  • pkg/operator/helpers/helpers.go (1 hunks)
  • pkg/operator/helpers/helpers_test.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (4 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • go.mod
🧰 Additional context used
🧠 Learnings (13)
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • manifests/cluster-manager/hub/grpc-server/service.yaml
  • pkg/operator/helpers/helpers_test.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
  • pkg/operator/helpers/helpers.go
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go
📚 Learning: 2025-08-04T08:58:41.865Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: manifests/klusterlet/management/klusterlet-registration-deployment.yaml:111-115
Timestamp: 2025-08-04T08:58:41.865Z
Learning: In OCM klusterlet deployments, gRPC authentication uses different file naming conventions than CSR/kube authentication: gRPC auth expects config.yaml files (/spoke/bootstrap/config.yaml and /spoke/hub-kubeconfig/config.yaml) while CSR/kube auth uses kubeconfig files. The gRPC driver explicitly creates config.yaml files in the secret data via additionalSecretData["config.yaml"] = d.configTemplate.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • manifests/cluster-manager/hub/grpc-server/service.yaml
📚 Learning: 2025-09-24T00:18:33.339Z
Learnt from: zhiweiyin318
Repo: open-cluster-management-io/ocm PR: 1194
File: deploy/klusterlet/chart/klusterlet/templates/bootstrap_kubeconfig_secret.yaml:25-27
Timestamp: 2025-09-24T00:18:33.339Z
Learning: gRPC config in OCM klusterlet bootstrap secrets does not support multiHubBootstrapHubKubeConfigs scenarios - it is intentionally designed only for single hub bootstrap configurations.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-07-25T01:21:08.891Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1077
File: test/integration/registration/spokecluster_grpc_test.go:0-0
Timestamp: 2025-07-25T01:21:08.891Z
Learning: In OCM integration tests, gRPC and kube authentication mechanisms require different CSR handling approaches: gRPC authentication uses util.ApproveCSR since the hub controller signs client certificates, while kube authentication uses authn.ApproveSpokeClusterCSR to simulate the kube-controller-manager signing client certificates.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
📚 Learning: 2025-08-28T01:58:37.933Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:247-280
Timestamp: 2025-08-28T01:58:37.933Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor and should not be modified locally as changes may be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:05.882Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:128-135
Timestamp: 2025-08-28T01:58:05.882Z
Learning: Files in deploy/cluster-manager/chart/cluster-manager/crds/ and similar CRD directories are often copied from vendor/upstream sources and should not be modified directly to avoid conflicts during updates.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:23.958Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:192-225
Timestamp: 2025-08-28T01:58:23.958Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ and deploy/cluster-manager/config/crds/ directories are copied from vendor (open-cluster-management.io/api dependency) and should not be modified locally.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T04:09:12.357Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:94-176
Timestamp: 2025-08-28T04:09:12.357Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor/upstream sources and should not be modified directly.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:59:04.611Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:50.021Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:168-175
Timestamp: 2025-08-28T01:58:50.021Z
Learning: In the OCM project, CRD schemas come from the open-cluster-management.io/api dependency. Changes to CRD schemas should be made upstream in that API package, not in the local CRD YAML files which are generated/copied from the API types.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-09-16T03:04:38.251Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:48-48
Timestamp: 2025-09-16T03:04:38.251Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are properly updated via "make update" when vendor dependencies change (like open-cluster-management.io/api updates) and validated by "make verify". The issue is only with local hand-edits, not legitimate vendor update processes.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T02:00:03.385Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:278-280
Timestamp: 2025-08-28T02:00:03.385Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are copied from vendor code and should not be modified locally. Grammar or other issues in these files should be reported upstream to the vendor instead.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-06T06:00:53.508Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: deploy/cluster-manager/config/rbac/cluster_role.yaml:165-168
Timestamp: 2025-08-06T06:00:53.508Z
Learning: In OCM gRPC deployments, both the cluster-manager operator ClusterRole and the gRPC server ClusterRole need "create" permission on "managedclustersets/join" resources for proper bootstrapping of managed clusters.

Applied to files:

  • manifests/cluster-manager/hub/grpc-server/clusterrole.yaml
🧬 Code graph analysis (5)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (2)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerHostNames (935-983)
pkg/operator/helpers/queuekey.go (1)
  • GRPCServerSecret (48-48)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerEndpointType (985-1000)
pkg/operator/helpers/helpers_test.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCServerHostNames (935-983)
  • GRPCServerEndpointType (985-1000)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)
pkg/operator/helpers/queuekey.go (6)
  • GRPCServerSecret (48-48)
  • ClusterManagerNamespace (51-56)
  • SignerSecret (45-45)
  • RegistrationWebhookSecret (40-40)
  • WorkWebhookSecret (42-42)
  • CaBundleConfigmap (46-46)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (2)
pkg/operator/helpers/queuekey.go (1)
  • ClusterManagerNamespace (51-56)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: unit
  • GitHub Check: e2e-singleton
  • GitHub Check: verify
  • GitHub Check: integration
  • GitHub Check: e2e
  • GitHub Check: build
  • GitHub Check: e2e-hosted
🔇 Additional comments (12)
manifests/cluster-manager/hub/grpc-server/clusterrole.yaml (1)

18-20: Verify whether the replicasets permission is actually required for LoadBalancer endpoint discovery.

My codebase search found no evidence that the gRPC server implementation accesses native Kubernetes ReplicaSets (from the apps API group). Extensive searches across controller code returned only references to the custom ManifestWorkReplicaSet resource, not native replicasets.

While the RBAC rule is syntactically correct and properly formatted, I cannot confirm from the available code that the gRPC server actually needs this permission for LoadBalancer service support. The PR adds support for LoadBalancer endpoint type, but the endpoint discovery mechanism that would require replicaset access is not evident in the searchable code paths.

Additionally, verify whether other RBAC rules are needed for complete LoadBalancer support (e.g., services, services/status, or endpoints resources), as the current rule only grants access to replicasets.

Suggested actions:

  1. Confirm the gRPC server controller code actually queries native Kubernetes ReplicaSets for LoadBalancer endpoint discovery
  2. Verify all necessary RBAC permissions are included for the complete LoadBalancer feature (check if services/endpoints access is also needed)
  3. If this permission is not actively used, consider removing it or documenting why it is included as forward-compatibility
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)

233-239: Correct wiring of GRPC auth flag and endpoint type

Setting GRPCAuthEnabled via helpers.GRPCAuthEnabled and only deriving GRPCEndpointType when it is true is consistent with the helper semantics and avoids unnecessary endpoint processing when gRPC auth is off. Looks good.

manifests/config.go (1)

43-47: HubConfig extended cleanly for GRPC endpoint type

Adding GRPCEndpointType alongside other gRPC fields in HubConfig is straightforward and aligns with how templates and controllers consume it. No issues from this change alone.

manifests/cluster-manager/hub/grpc-server/service.yaml (1)

17-27: Service template logic matches GRPC endpoint type semantics

Conditionally switching to port: 443 and type: LoadBalancer when .GRPCEndpointType == "loadBalancer" and defaulting to port: 8090/ClusterIP otherwise is consistent with the new endpoint type and with the controller tests. The templating/indentation is valid.

pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1)

825-958: Good coverage of GRPC service type/port variants

The new TestGRPCServiceLoadBalancerType exercises the GRPC service behavior for LoadBalancer, hostname, and default configurations by inspecting the created Service objects across hub and management clients. Assertions on ServiceType and Port align with the templating logic and help prevent regressions.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (2)

5-7: New imports are appropriate and used

The added fmt, strings, and certrotation imports are all used in the new tests and keep dependencies localized to test code. No issues here.

Also applies to: 25-26


240-254: Stronger validation of GRPC server secret contents

Extending TestCertRotationGRPCAuth to assert the GRPC server secret exists and contains both tls.crt and tls.key materially improves the test: it now confirms actual TLS material is written, not just that a Secret object was created. This is a good tightening of expectations.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1)

242-291: LGTM! Certificate SANs will now stay in sync with load balancer changes.

The implementation correctly addresses the previous concern about stale certificate SANs. By resolving hostnames on every sync (line 249) and updating the existing rotation's HostNames (line 255), the certificate will reflect current load balancer endpoints rather than caching the initial values.

The error aggregation pattern (lines 242, 251, 287, 291) ensures that hostname resolution failures and target rotation errors are properly collected and reported without short-circuiting the sync process.

deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (1)

583-679: CRD schema extensions look consistent.

The new loadBalancer and route endpoint configuration blocks are symmetrically defined for both grpc (lines 583-620) and https (lines 642-679) endpoints, following the same structure as the existing hostname configuration.

Based on learnings, CRD files in this directory are copied from the open-cluster-management.io/api vendor dependency. These changes should originate from that upstream API package rather than being hand-edited locally.

Based on learnings

pkg/operator/helpers/helpers.go (2)

951-975: LoadBalancer endpoint resolution is correctly implemented.

The logic properly:

  • Appends the custom host if configured (lines 952-954)
  • Fetches the gRPC service using the correct naming convention (lines 956-958)
  • Returns informative errors when the service or ingress is missing (lines 959-967)
  • Extracts both IP and hostname from the first ingress entry (lines 969-975)

This allows certificates to include all relevant SANs for LoadBalancer-exposed gRPC endpoints.


985-1000: Endpoint type detection provides safe defaults.

GRPCServerEndpointType correctly:

  • Returns hostname as the default when ServerConfiguration is nil or no gRPC endpoint exists
  • Returns hostname when the gRPC endpoint config is nil
  • Otherwise returns the configured endpoint type

This defensive approach ensures the system can operate with sensible defaults while respecting explicit configuration.

pkg/operator/helpers/helpers_test.go (1)

1880-2384: LGTM! Comprehensive test coverage for GRPC endpoint resolution.

The test suites thoroughly exercise both GRPCServerHostNames and GRPCServerEndpointType:

TestGRPCServerHostNames covers:

  • Default behaviors with nil/empty configurations (lines 1890-1959)
  • Hostname endpoints with valid and empty hosts (lines 1961-2011)
  • LoadBalancer endpoints with IP, hostname, and both (lines 2013-2135)
  • Error conditions: service not found and missing ingress (lines 2137-2195)

TestGRPCServerEndpointType validates:

  • Safe defaults when configuration is missing or incomplete (lines 2224-2285)
  • Correct type detection for hostname and loadBalancer (lines 2287-2327)
  • Edge cases like nil GRPC config and multiple endpoints (lines 2329-2373)

The use of fake Kubernetes clients with pre-populated Service fixtures (e.g., lines 2036-2050) properly simulates real cluster behavior.

@zhiweiyin318
Copy link
Member Author

/assign @skeeey
/assign @qiujian16


if len(gRPCService.Status.LoadBalancer.Ingress[0].Hostname) != 0 {
hostNames = append(hostNames, gRPCService.Status.LoadBalancer.Ingress[0].Hostname)
}
Copy link
Member

Choose a reason for hiding this comment

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

do we need to check both of ip and hostname are empty at the same time?

Copy link
Member Author

Choose a reason for hiding this comment

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

- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
- apiGroups: ["apps"]
Copy link
Member

Choose a reason for hiding this comment

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

why we need to get replicasets?

Copy link
Member Author

Choose a reason for hiding this comment

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

there is a warning in grpc-server pod
W1117 03:24:35.902536 1 builder.go:272] unable to get owner reference (falling back to namespace): replicasets.apps "cluster-manager-grpc-server-7fb9c4b846" is forbidden: User "system:serviceaccount:open-cluster-management-hub:grpc-server-sa" cannot get resource "replicasets" in API group "apps" in the namespace "open-cluster-management-hub"

Copy link
Member

Choose a reason for hiding this comment

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

I think it is because the server is intending to get the podName from envvar? https://github.com/openshift/library-go/blob/master/pkg/operator/events/recorder.go#L59. We do not need this permission of podName envvar is set.

Copy link
Member Author

Choose a reason for hiding this comment

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

removed

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

🧹 Nitpick comments (4)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1)

825-958: New GRPC service LoadBalancer/ClusterIP test covers key scenarios

The table‑driven TestGRPCServiceLoadBalancerType nicely validates service Type and Port for loadBalancer, hostname, and default configurations against the rendered manifests, and the action scan across hub/management clients is consistent with existing tests.

One small nit: in the first two cases you set Protocol: "grpc". To avoid drift with GRPCServerEndpointType, consider using Protocol: operatorapiv1.GRPCAuthType instead so the tests track the enum constant rather than a magic string.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)

362-716: GRPC hostname rotation tests look good; consider relaxing order sensitivity

TestCertRotationGRPCServerHostNames exercises the main GRPC endpoint variants (LoadBalancer with IP, LoadBalancer with hostname, explicit hostname) plus the key error paths (service missing, ingress missing). Validating that the GRPC target rotation exists only when hostname discovery succeeds, and that its HostNames contain the default service DNS plus the LB/IP or custom hostname, gives strong coverage of the new helper behavior.

Two minor nits:

  • The checks for grpcRotation.HostNames compare entries by index; if GRPCServerHostNames ever changes the ordering while preserving the same set of names, these tests will fail. You could make the assertions order‑insensitive (e.g., sort both slices or compare via a map) to make them more robust.
  • When locating the GRPC rotation you take &rotation on the range variable. It’s safe here because you break immediately, but if this is ever refactored to collect multiple pointers, copying to a local (r := rotation; grpcRotation = &r) would avoid the common Go gotcha with range variables.

Otherwise the structure and use of certrotation.TargetRotation and helpers.GRPCServerSecret look consistent with the intended design.

pkg/operator/helpers/helpers.go (1)

935-990: GRPCServerHostNames / GRPCServerEndpointType are sound; consider preserving the underlying Service error

The hostname resolution and endpoint‑type selection match the GRPC endpoint semantics and the new CRD enums: you seed with the internal *-grpc-server DNS, skip non‑gRPC endpoints, handle hostname and loadBalancer types (including the configured host plus LB IP/hostname), and default to hostname when configuration is absent or incomplete. This aligns with the cert‑rotation controller’s expectations.

One small improvement: when the Service Get fails, you currently drop the underlying error. Keeping it helps debugging cluster‑side issues:

-		gRPCService, err := kubeClient.CoreV1().Services(clusterManagerNamespace).
-			Get(context.TODO(), serviceName, metav1.GetOptions{})
-		if err != nil {
-			return hostNames, fmt.Errorf("failed to find service %s in namespace %s",
-				serviceName, clusterManagerNamespace)
-		}
+		gRPCService, err := kubeClient.CoreV1().Services(clusterManagerNamespace).
+			Get(context.TODO(), serviceName, metav1.GetOptions{})
+		if err != nil {
+			return hostNames, fmt.Errorf("failed to find service %s in namespace %s: %w",
+				serviceName, clusterManagerNamespace, err)
+		}

Otherwise, the functions look correct and well‑covered by tests.

Also applies to: 992-1007

pkg/operator/helpers/helpers_test.go (1)

1880-2215: GRPC helper tests are thorough; add one case for the “empty ingress fields” error path

The new TestGRPCServerHostNames and TestGRPCServerEndpointType cases exercise the main success and failure scenarios (nil/empty config, non‑gRPC endpoints, hostname and loadBalancer variants, and most LB error conditions) and line up well with the helper logic.

For complete coverage of the LB error handling, consider adding one more TestGRPCServerHostNames case where LoadBalancer.Ingress has a single entry but both IP and Hostname are empty, asserting expectError: true. That would exercise the failed to find ip or hostname in the ingress branch.

Also applies to: 2217-2381

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fed584 and 6be3212.

⛔ Files ignored due to path filters (5)
  • go.sum is excluded by !**/*.sum
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go is excluded by !vendor/**
📒 Files selected for processing (13)
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml (1 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (2 hunks)
  • go.mod (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/service.yaml (1 hunks)
  • manifests/config.go (1 hunks)
  • pkg/operator/helpers/helpers.go (1 hunks)
  • pkg/operator/helpers/helpers_test.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (4 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • go.mod
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
🧰 Additional context used
🧠 Learnings (13)
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • manifests/cluster-manager/hub/grpc-server/service.yaml
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
  • pkg/operator/helpers/helpers_test.go
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go
  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-08-28T01:59:04.611Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-07-25T01:21:08.891Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1077
File: test/integration/registration/spokecluster_grpc_test.go:0-0
Timestamp: 2025-07-25T01:21:08.891Z
Learning: In OCM integration tests, gRPC and kube authentication mechanisms require different CSR handling approaches: gRPC authentication uses util.ApproveCSR since the hub controller signs client certificates, while kube authentication uses authn.ApproveSpokeClusterCSR to simulate the kube-controller-manager signing client certificates.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-08-28T01:58:05.882Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:128-135
Timestamp: 2025-08-28T01:58:05.882Z
Learning: Files in deploy/cluster-manager/chart/cluster-manager/crds/ and similar CRD directories are often copied from vendor/upstream sources and should not be modified directly to avoid conflicts during updates.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:37.933Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:247-280
Timestamp: 2025-08-28T01:58:37.933Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor and should not be modified locally as changes may be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:23.958Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:192-225
Timestamp: 2025-08-28T01:58:23.958Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ and deploy/cluster-manager/config/crds/ directories are copied from vendor (open-cluster-management.io/api dependency) and should not be modified locally.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T04:09:12.357Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:94-176
Timestamp: 2025-08-28T04:09:12.357Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor/upstream sources and should not be modified directly.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:50.021Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:168-175
Timestamp: 2025-08-28T01:58:50.021Z
Learning: In the OCM project, CRD schemas come from the open-cluster-management.io/api dependency. Changes to CRD schemas should be made upstream in that API package, not in the local CRD YAML files which are generated/copied from the API types.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-09-16T03:04:38.251Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:48-48
Timestamp: 2025-09-16T03:04:38.251Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are properly updated via "make update" when vendor dependencies change (like open-cluster-management.io/api updates) and validated by "make verify". The issue is only with local hand-edits, not legitimate vendor update processes.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-04T08:58:41.865Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: manifests/klusterlet/management/klusterlet-registration-deployment.yaml:111-115
Timestamp: 2025-08-04T08:58:41.865Z
Learning: In OCM klusterlet deployments, gRPC authentication uses different file naming conventions than CSR/kube authentication: gRPC auth expects config.yaml files (/spoke/bootstrap/config.yaml and /spoke/hub-kubeconfig/config.yaml) while CSR/kube auth uses kubeconfig files. The gRPC driver explicitly creates config.yaml files in the secret data via additionalSecretData["config.yaml"] = d.configTemplate.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-09-24T00:18:33.339Z
Learnt from: zhiweiyin318
Repo: open-cluster-management-io/ocm PR: 1194
File: deploy/klusterlet/chart/klusterlet/templates/bootstrap_kubeconfig_secret.yaml:25-27
Timestamp: 2025-09-24T00:18:33.339Z
Learning: gRPC config in OCM klusterlet bootstrap secrets does not support multiHubBootstrapHubKubeConfigs scenarios - it is intentionally designed only for single hub bootstrap configurations.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-07-14T09:30:25.378Z
Learnt from: zhujian7
Repo: open-cluster-management-io/ocm PR: 1070
File: SECURITY-INSIGHTS.yml:44-44
Timestamp: 2025-07-14T09:30:25.378Z
Learning: In the open-cluster-management-io/ocm repository, the team prefers to use commit SHAs instead of tags for GitHub Actions dependencies like dependency-review-action for security reasons, as commit SHAs are immutable while tags can be moved.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-07-01T05:27:25.998Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1058
File: pkg/server/services/cluster/cluster.go:48-64
Timestamp: 2025-07-01T05:27:25.998Z
Learning: The ClusterService struct in pkg/server/services/cluster/cluster.go implements the server.Service interface, so method names like List() cannot be renamed as they must match the interface definition exactly.

Applied to files:

  • pkg/operator/helpers/helpers.go
🧬 Code graph analysis (5)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (2)
pkg/operator/helpers/queuekey.go (6)
  • GRPCServerSecret (48-48)
  • ClusterManagerNamespace (51-56)
  • SignerSecret (45-45)
  • RegistrationWebhookSecret (40-40)
  • WorkWebhookSecret (42-42)
  • CaBundleConfigmap (46-46)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
pkg/operator/helpers/helpers_test.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCServerHostNames (935-990)
  • GRPCServerEndpointType (992-1007)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerEndpointType (992-1007)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (2)
pkg/operator/helpers/queuekey.go (1)
  • ClusterManagerNamespace (51-56)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (2)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerHostNames (935-990)
pkg/operator/helpers/queuekey.go (1)
  • GRPCServerSecret (48-48)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: e2e-hosted
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e
  • GitHub Check: integration
  • GitHub Check: unit
  • GitHub Check: verify
🔇 Additional comments (9)
manifests/config.go (1)

46-46: GRPCEndpointType addition is consistent with helper usage

Adding GRPCEndpointType string to HubConfig matches helpers.GRPCServerEndpointType’s return type and safely defaults to "" when gRPC auth is disabled.

pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)

233-239: gRPC auth and endpoint-type wiring into HubConfig looks correct

Using helpers.GRPCAuthEnabled and, when true, helpers.GRPCServerEndpointType to populate config.GRPCEndpointType cleanly exposes the endpoint choice to manifests without affecting non‑gRPC setups.

manifests/cluster-manager/hub/grpc-server/service.yaml (1)

17-27: Conditional port/type based on GRPCEndpointType is sound

The template correctly switches the service to type: LoadBalancer with port: 443 when .GRPCEndpointType == "loadBalancer", and otherwise keeps ClusterIP on 8090 while still targeting container port 8090. Indentation keeps the rendered YAML valid.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (3)

3-29: New imports are aligned with added GRPC rotation tests

fmt, strings, and the certrotation package are all used in the new GRPC hostname/error‑path assertions and TLS rotation checks; the import changes are consistent with the added tests.


174-179: Including GRPCServerSecret in secret informers is appropriate

Adding helpers.GRPCServerSecret to the secretInformers map ensures the cert‑rotation controller can watch and drive rotation for the GRPC server TLS secret alongside the existing signer/webhook secrets.


241-254: Extra validation of GRPC server TLS secret improves coverage

Extending the “Enable GRPC” case in TestCertRotationGRPCAuth to fetch helpers.GRPCServerSecret and assert presence of tls.crt and tls.key is a good sanity check that rotation produced a structurally valid TLS secret.

deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (1)

583-620: GRPC/HTTPS loadBalancer & route schema extensions look consistent

The new loadBalancer/route objects and the extended type enums under both grpc and https match the existing hostname shape and look API‑compatible. Assuming this manifest was regenerated from the updated open-cluster-management.io/api types (via make update) rather than hand‑edited, I don’t see issues here.

Based on learnings

Also applies to: 642-679

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1)

242-291: Dynamic GRPC hostname handling and aggregated error reporting look correct

Resolving GRPC hostnames on every sync, updating existing rotations when present, and aggregating both hostname‑resolution and target‑rotation errors via NewMultiLineAggregate gives up‑to‑date SANs without regressing the other cert paths. The slice mutation and rotationMap updates are safe with the current struct/slice usage.

deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (1)

583-620: CRD endpoint exposure schema matches the new GRPC/HTTPS endpoint types

The added loadBalancer/route blocks and extended type enums under serverConfiguration.endpointsExposure.grpc/https are aligned with the new endpoint types used in code and tests. As long as this CRD came from the updated open-cluster-management.io/api (e.g., via make update) rather than manual edits, it looks good.

Based on learnings

Also applies to: 642-679

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

🧹 Nitpick comments (2)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)

362-716: Good coverage of GRPC server hostnames; consider reducing order coupling

TestCertRotationGRPCServerHostNames does a nice job covering:

  • LoadBalancer with IP and hostname
  • Custom hostname endpoint type
  • Error paths (service missing, ingress missing) and their impact on rotationMap.

One minor suggestion: the assertions currently rely on the exact order of grpcRotation.HostNames. To make the tests more resilient to benign implementation changes, you could compare sorted slices or treat the hostnames as a set instead of checking HostNames[i] by index.

deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (1)

569-620: CRD extension for grpc/https endpoint types looks consistent; ensure it stays in sync with vendor‑generated CRDs

The new loadBalancer and route blocks under both grpc and https, plus the extended type enums, line up with the new endpoint exposure types introduced in the API and controllers.

However, per prior guidance, this OLM catalog CRD is copied from the API/vendor source and is prone to drift if edited manually. Please ensure that:

  • These changes are generated from the updated open-cluster-management.io/api CRD definitions (or via the usual sync script), not hand‑maintained.
  • The CRD here matches the copies under deploy/cluster-manager/config/crds/... and the Helm chart CRDs so all three stay consistent.

[based on learnings]

Also applies to: 628-679

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6be3212 and 2164a5c.

⛔ Files ignored due to path filters (5)
  • go.sum is excluded by !**/*.sum
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go is excluded by !vendor/**
📒 Files selected for processing (13)
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml (1 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (2 hunks)
  • go.mod (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/service.yaml (1 hunks)
  • manifests/config.go (1 hunks)
  • pkg/operator/helpers/helpers.go (1 hunks)
  • pkg/operator/helpers/helpers_test.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (4 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go
  • manifests/cluster-manager/hub/grpc-server/service.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
🧰 Additional context used
🧠 Learnings (11)
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/helpers/helpers.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
  • pkg/operator/helpers/helpers_test.go
📚 Learning: 2025-07-25T01:21:08.891Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1077
File: test/integration/registration/spokecluster_grpc_test.go:0-0
Timestamp: 2025-07-25T01:21:08.891Z
Learning: In OCM integration tests, gRPC and kube authentication mechanisms require different CSR handling approaches: gRPC authentication uses util.ApproveCSR since the hub controller signs client certificates, while kube authentication uses authn.ApproveSpokeClusterCSR to simulate the kube-controller-manager signing client certificates.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
📚 Learning: 2025-08-04T08:58:41.865Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: manifests/klusterlet/management/klusterlet-registration-deployment.yaml:111-115
Timestamp: 2025-08-04T08:58:41.865Z
Learning: In OCM klusterlet deployments, gRPC authentication uses different file naming conventions than CSR/kube authentication: gRPC auth expects config.yaml files (/spoke/bootstrap/config.yaml and /spoke/hub-kubeconfig/config.yaml) while CSR/kube auth uses kubeconfig files. The gRPC driver explicitly creates config.yaml files in the secret data via additionalSecretData["config.yaml"] = d.configTemplate.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-08-28T01:59:04.611Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.

Applied to files:

  • go.mod
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
📚 Learning: 2025-07-14T09:30:25.378Z
Learnt from: zhujian7
Repo: open-cluster-management-io/ocm PR: 1070
File: SECURITY-INSIGHTS.yml:44-44
Timestamp: 2025-07-14T09:30:25.378Z
Learning: In the open-cluster-management-io/ocm repository, the team prefers to use commit SHAs instead of tags for GitHub Actions dependencies like dependency-review-action for security reasons, as commit SHAs are immutable while tags can be moved.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-08-28T01:58:50.021Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:168-175
Timestamp: 2025-08-28T01:58:50.021Z
Learning: In the OCM project, CRD schemas come from the open-cluster-management.io/api dependency. Changes to CRD schemas should be made upstream in that API package, not in the local CRD YAML files which are generated/copied from the API types.

Applied to files:

  • pkg/operator/helpers/helpers.go
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-07-01T05:27:25.998Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1058
File: pkg/server/services/cluster/cluster.go:48-64
Timestamp: 2025-07-01T05:27:25.998Z
Learning: The ClusterService struct in pkg/server/services/cluster/cluster.go implements the server.Service interface, so method names like List() cannot be renamed as they must match the interface definition exactly.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-08-28T01:58:37.933Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:247-280
Timestamp: 2025-08-28T01:58:37.933Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor and should not be modified locally as changes may be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:05.882Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:128-135
Timestamp: 2025-08-28T01:58:05.882Z
Learning: Files in deploy/cluster-manager/chart/cluster-manager/crds/ and similar CRD directories are often copied from vendor/upstream sources and should not be modified directly to avoid conflicts during updates.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:23.958Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:192-225
Timestamp: 2025-08-28T01:58:23.958Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ and deploy/cluster-manager/config/crds/ directories are copied from vendor (open-cluster-management.io/api dependency) and should not be modified locally.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T04:09:12.357Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:94-176
Timestamp: 2025-08-28T04:09:12.357Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor/upstream sources and should not be modified directly.

Applied to files:

  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
🧬 Code graph analysis (4)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerEndpointType (992-1007)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (2)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerHostNames (935-990)
pkg/operator/helpers/queuekey.go (1)
  • GRPCServerSecret (48-48)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (2)
pkg/operator/helpers/queuekey.go (6)
  • GRPCServerSecret (48-48)
  • ClusterManagerNamespace (51-56)
  • SignerSecret (45-45)
  • RegistrationWebhookSecret (40-40)
  • WorkWebhookSecret (42-42)
  • CaBundleConfigmap (46-46)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
pkg/operator/helpers/helpers_test.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCServerHostNames (935-990)
  • GRPCServerEndpointType (992-1007)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: e2e
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e-hosted
  • GitHub Check: unit
  • GitHub Check: integration
  • GitHub Check: verify
🔇 Additional comments (9)
go.mod (1)

43-43: API module bump looks consistent with CRD/schema changes

Updating open-cluster-management.io/api here aligns with the new endpoint exposure fields introduced elsewhere in the PR. Please double‑check that:

  • There are no breaking API changes for existing callers.
  • go mod tidy and vendoring/regeneration steps have been run so generated CRDs and clients match this version.
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)

233-239: GRPC auth and endpoint type wiring looks correct

Populating config.GRPCAuthEnabled and config.GRPCEndpointType via the helpers centralizes the GRPC server behavior in the HubConfig and matches the new helper semantics (defaulting to hostname when unset). No issues spotted here; downstream reconcilers and templates should now have all the information they need.

manifests/config.go (1)

45-47: HubConfig extension for GRPC endpoint type is reasonable

Adding GRPCEndpointType string alongside the existing GRPC fields matches the controller wiring and enables templates to branch on endpoint type (hostname vs loadBalancer/route). The field is non‑intrusive and safe when GRPC auth is disabled.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)

242-254: Stronger validation of GRPC server secret contents

The updated GRPC auth test now actually fetches the GRPC server secret and asserts tls.crt / tls.key presence, not just rotationMap state. This closes an important gap and ensures the rotation logic results in a viable serving secret.

deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (1)

583-620: CRD schema additions align with the loadBalancer feature.

The new loadBalancer and route endpoint exposure types are properly structured with caBundle and host fields matching the existing hostname pattern. The schema changes are consistent with the feature objectives.

Based on learnings: These CRD files are copied from the open-cluster-management.io/api dependency. If any schema adjustments are needed, they should be made upstream in that API package rather than here.

pkg/operator/helpers/helpers.go (2)

935-990: LGTM! Comprehensive LoadBalancer endpoint handling.

The updated GRPCServerHostNames implementation correctly:

  • Filters for GRPC protocol endpoints
  • Handles the LoadBalancer type with thorough validation (service lookup, ingress presence, IP/hostname availability)
  • Appends both custom LoadBalancer.Host and discovered ingress IP/hostname to the SANs list
  • Returns descriptive errors for each failure scenario

The Route case TODO is appropriately deferred, with follow-up issue #1260 already created per the PR comments.


992-1007: LGTM! Clean endpoint type resolver.

The GRPCServerEndpointType function correctly defaults to Hostname when:

  • Server configuration is nil
  • No GRPC endpoints are configured
  • GRPC config is nil

And properly returns the configured type otherwise.

pkg/operator/helpers/helpers_test.go (2)

1880-2215: LGTM! Comprehensive test coverage for hostname resolution.

The TestGRPCServerHostNames test suite thoroughly validates:

  • Default behavior (nil/empty server configuration)
  • Protocol filtering (non-GRPC endpoints ignored)
  • Hostname endpoints (valid hosts and empty/whitespace-only hosts)
  • LoadBalancer endpoints across multiple scenarios:
    • Custom host plus ingress IP
    • Hostname-only ingress
    • Both IP and hostname in ingress
    • Error cases: service not found, empty ingress list

The test cases properly use fake Kubernetes clients with existingObjects to simulate API responses and verify error handling.


2217-2384: LGTM! Complete coverage for endpoint type resolution.

The TestGRPCServerEndpointType test suite validates all scenarios:

  • Default fallback to Hostname when config is nil/empty
  • Protocol filtering (non-GRPC returns default)
  • Nil GRPC config handling
  • Correct type returned for both Hostname and LoadBalancer configurations
  • Mixed endpoint lists (GRPC identified among other protocols)

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

♻️ Duplicate comments (2)
pkg/operator/helpers/helpers.go (1)

983-985: Route case still TODO; ensure it’s tracked and tested.

Implement route host inclusion (e.g., append endpoint.GRPC.Route.Host) and add tests. I see a follow‑up issue was mentioned earlier; confirm linkage and priority.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1)

246-269: Critical: hostname refresh isn’t persisted back to rotationMap.

After updating rotations.targetRotations[i].HostNames, you must save rotations back to c.rotationMap; otherwise the change is lost. Same issue was flagged earlier.

 		} else if hasRotation(rotations.targetRotations, helpers.GRPCServerSecret) {
 			for i := range rotations.targetRotations {
 				if rotations.targetRotations[i].Name == helpers.GRPCServerSecret {
 					rotations.targetRotations[i].HostNames = hostNames
 					break
 				}
 			}
+			c.rotationMap[clustermanagerName] = rotations
 		} else {
 			rotations.targetRotations = append(rotations.targetRotations, certrotation.TargetRotation{
 				Namespace: clustermanagerNamespace,
 				Name:      helpers.GRPCServerSecret,
 				Validity:  TargetCertValidity,
 				HostNames: hostNames,
 				Lister:    c.secretInformers[helpers.GRPCServerSecret].Lister(),
 				Client:    c.kubeClient.CoreV1(),
 			})
 			c.rotationMap[clustermanagerName] = rotations
 		}
🧹 Nitpick comments (4)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1)

825-959: Add targetPort assertion to prevent regressions.

Also assert service.Spec.Ports[0].TargetPort == 8090 in all cases, since port switches to 443 for LB while targetPort remains 8090.

-                            actualServicePort = service.Spec.Ports[0].Port
+                            actualServicePort = service.Spec.Ports[0].Port
+                            if service.Spec.Ports[0].TargetPort.IntVal != 8090 {
+                                t.Errorf("Expected targetPort 8090, got %d", service.Spec.Ports[0].TargetPort.IntVal)
+                            }
pkg/operator/helpers/helpers_test.go (1)

1882-2196: Nice coverage; add a route-case test when implemented.

Once route handling is added, include a case for grpc.type=route to assert host inclusion and error behavior.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)

362-716: Add a refresh test to detect hostname updates across syncs.

Simulate LB ingress change and assert the rotation hostnames update after a second sync. This would have caught the missing map write-back.

// Add near existing tests
func TestCertRotationGRPCHostnamesRefreshOnChange(t *testing.T) {
  ns := helpers.ClusterManagerNamespace(testClusterManagerNameDefault, operatorapiv1.InstallModeDefault)
  cm := newClusterManager(testClusterManagerNameDefault, operatorapiv1.InstallModeDefault)
  cm.Spec.ServerConfiguration = &operatorapiv1.ServerConfiguration{
    EndpointsExposure: []operatorapiv1.EndpointExposure{{
      Protocol: operatorapiv1.GRPCAuthType,
      GRPC: &operatorapiv1.Endpoint{Type: operatorapiv1.EndpointTypeLoadBalancer},
    }},
  }
  svcName := testClusterManagerNameDefault + "-grpc-server"

  kubeClient := fakekube.NewSimpleClientset(
    &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}},
    &corev1.Service{
      ObjectMeta: metav1.ObjectMeta{Name: svcName, Namespace: ns},
      Status: corev1.ServiceStatus{LoadBalancer: corev1.LoadBalancerStatus{
        Ingress: []corev1.LoadBalancerIngress{{IP: "1.1.1.1"}},
      }},
    },
  )
  // wire informers/controller like in other tests...
  // first sync
  // mutate Service to new ingress (e.g., 2.2.2.2) and update in fake client
  // second sync
  // assert rotationMap entry for GRPCServerSecret hostnames now contains 2.2.2.2 (not 1.1.1.1)
}
pkg/operator/helpers/helpers.go (1)

935-990: Improve LB resolution: include err, handle all ingress entries, de‑dupe.

  • Wrap the underlying Get error for easier debugging.
  • Append all ingress IPs/hostnames (not just index 0).
  • Avoid duplicates in hostNames.
- gRPCService, err := kubeClient.CoreV1().Services(clusterManagerNamespace).
-   Get(context.TODO(), serviceName, metav1.GetOptions{})
- if err != nil {
-   return hostNames, fmt.Errorf("failed to find service %s in namespace %s",
-     serviceName, clusterManagerNamespace)
- }
+ gRPCService, err := kubeClient.CoreV1().Services(clusterManagerNamespace).
+   Get(context.TODO(), serviceName, metav1.GetOptions{})
+ if err != nil {
+   return hostNames, fmt.Errorf("failed to get service %s in %s: %w",
+     serviceName, clusterManagerNamespace, err)
+ }
- if len(gRPCService.Status.LoadBalancer.Ingress) == 0 {
+ if len(gRPCService.Status.LoadBalancer.Ingress) == 0 {
    return hostNames, fmt.Errorf("failed to find ingress in the status of the service %s in namespace %s",
      serviceName, clusterManagerNamespace)
  }
-
- if len(gRPCService.Status.LoadBalancer.Ingress[0].IP) == 0 &&
-   len(gRPCService.Status.LoadBalancer.Ingress[0].Hostname) == 0 {
-   return hostNames, fmt.Errorf("failed to find ip or hostname in the ingress "+
-     "in the status of the service %s in namespace %s", serviceName, clusterManagerNamespace)
- }
-
- if len(gRPCService.Status.LoadBalancer.Ingress[0].IP) != 0 {
-   hostNames = append(hostNames, gRPCService.Status.LoadBalancer.Ingress[0].IP)
- }
-
- if len(gRPCService.Status.LoadBalancer.Ingress[0].Hostname) != 0 {
-   hostNames = append(hostNames, gRPCService.Status.LoadBalancer.Ingress[0].Hostname)
- }
+ added := map[string]struct{}{}
+ for _, h := range hostNames { added[h] = struct{}{} }
+ hasAny := false
+ for _, ing := range gRPCService.Status.LoadBalancer.Ingress {
+   if ip := strings.TrimSpace(ing.IP); ip != "" {
+     hasAny = true
+     if _, ok := added[ip]; !ok {
+       hostNames = append(hostNames, ip)
+       added[ip] = struct{}{}
+     }
+   }
+   if hn := strings.TrimSpace(ing.Hostname); hn != "" {
+     hasAny = true
+     if _, ok := added[hn]; !ok {
+       hostNames = append(hostNames, hn)
+       added[hn] = struct{}{}
+     }
+   }
+ }
+ if !hasAny {
+   return hostNames, fmt.Errorf("failed to find ip or hostname in service %s/%s ingress entries",
+     clusterManagerNamespace, serviceName)
+ }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2164a5c and d8d5aa0.

⛔ Files ignored due to path filters (5)
  • go.sum is excluded by !**/*.sum
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go is excluded by !vendor/**
📒 Files selected for processing (13)
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml (1 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (2 hunks)
  • go.mod (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/service.yaml (1 hunks)
  • manifests/config.go (1 hunks)
  • pkg/operator/helpers/helpers.go (1 hunks)
  • pkg/operator/helpers/helpers_test.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (4 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
  • manifests/config.go
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.
📚 Learning: 2025-08-04T08:58:41.865Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: manifests/klusterlet/management/klusterlet-registration-deployment.yaml:111-115
Timestamp: 2025-08-04T08:58:41.865Z
Learning: In OCM klusterlet deployments, gRPC authentication uses different file naming conventions than CSR/kube authentication: gRPC auth expects config.yaml files (/spoke/bootstrap/config.yaml and /spoke/hub-kubeconfig/config.yaml) while CSR/kube auth uses kubeconfig files. The gRPC driver explicitly creates config.yaml files in the secret data via additionalSecretData["config.yaml"] = d.configTemplate.

Applied to files:

  • manifests/cluster-manager/hub/grpc-server/service.yaml
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • manifests/cluster-manager/hub/grpc-server/service.yaml
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go
  • pkg/operator/helpers/helpers_test.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-08-28T01:59:04.611Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.

Applied to files:

  • go.mod
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-07-25T01:21:08.891Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1077
File: test/integration/registration/spokecluster_grpc_test.go:0-0
Timestamp: 2025-07-25T01:21:08.891Z
Learning: In OCM integration tests, gRPC and kube authentication mechanisms require different CSR handling approaches: gRPC authentication uses util.ApproveCSR since the hub controller signs client certificates, while kube authentication uses authn.ApproveSpokeClusterCSR to simulate the kube-controller-manager signing client certificates.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
📚 Learning: 2025-07-14T09:30:25.378Z
Learnt from: zhujian7
Repo: open-cluster-management-io/ocm PR: 1070
File: SECURITY-INSIGHTS.yml:44-44
Timestamp: 2025-07-14T09:30:25.378Z
Learning: In the open-cluster-management-io/ocm repository, the team prefers to use commit SHAs instead of tags for GitHub Actions dependencies like dependency-review-action for security reasons, as commit SHAs are immutable while tags can be moved.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-08-28T01:58:50.021Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:168-175
Timestamp: 2025-08-28T01:58:50.021Z
Learning: In the OCM project, CRD schemas come from the open-cluster-management.io/api dependency. Changes to CRD schemas should be made upstream in that API package, not in the local CRD YAML files which are generated/copied from the API types.

Applied to files:

  • pkg/operator/helpers/helpers.go
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-07-01T05:27:25.998Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1058
File: pkg/server/services/cluster/cluster.go:48-64
Timestamp: 2025-07-01T05:27:25.998Z
Learning: The ClusterService struct in pkg/server/services/cluster/cluster.go implements the server.Service interface, so method names like List() cannot be renamed as they must match the interface definition exactly.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-08-28T01:58:23.958Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:192-225
Timestamp: 2025-08-28T01:58:23.958Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ and deploy/cluster-manager/config/crds/ directories are copied from vendor (open-cluster-management.io/api dependency) and should not be modified locally.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:37.933Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:247-280
Timestamp: 2025-08-28T01:58:37.933Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor and should not be modified locally as changes may be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:05.882Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:128-135
Timestamp: 2025-08-28T01:58:05.882Z
Learning: Files in deploy/cluster-manager/chart/cluster-manager/crds/ and similar CRD directories are often copied from vendor/upstream sources and should not be modified directly to avoid conflicts during updates.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T04:09:12.357Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:94-176
Timestamp: 2025-08-28T04:09:12.357Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor/upstream sources and should not be modified directly.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-09-16T03:04:38.251Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:48-48
Timestamp: 2025-09-16T03:04:38.251Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are properly updated via "make update" when vendor dependencies change (like open-cluster-management.io/api updates) and validated by "make verify". The issue is only with local hand-edits, not legitimate vendor update processes.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-10-10T02:50:14.188Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1204
File: manifests/cluster-manager/hub/crds/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml:88-91
Timestamp: 2025-10-10T02:50:14.188Z
Learning: Kubernetes CustomResourceDefinition (CRD) OpenAPI v3 schema does not support the `deprecated: true` property for individual fields. Field-level deprecation must be documented in the description field only. The formal `deprecated` property is not supported by Kubernetes CRD tooling.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T02:00:03.385Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:278-280
Timestamp: 2025-08-28T02:00:03.385Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are copied from vendor code and should not be modified locally. Grammar or other issues in these files should be reported upstream to the vendor instead.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-06T06:00:53.508Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: deploy/cluster-manager/config/rbac/cluster_role.yaml:165-168
Timestamp: 2025-08-06T06:00:53.508Z
Learning: In OCM gRPC deployments, both the cluster-manager operator ClusterRole and the gRPC server ClusterRole need "create" permission on "managedclustersets/join" resources for proper bootstrapping of managed clusters.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
🧬 Code graph analysis (4)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (2)
pkg/operator/helpers/queuekey.go (1)
  • ClusterManagerNamespace (51-56)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
pkg/operator/helpers/helpers_test.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCServerHostNames (935-990)
  • GRPCServerEndpointType (992-1007)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (2)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (922-933)
  • GRPCServerHostNames (935-990)
pkg/operator/helpers/queuekey.go (1)
  • GRPCServerSecret (48-48)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (2)
pkg/operator/helpers/queuekey.go (6)
  • GRPCServerSecret (48-48)
  • ClusterManagerNamespace (51-56)
  • SignerSecret (45-45)
  • RegistrationWebhookSecret (40-40)
  • WorkWebhookSecret (42-42)
  • CaBundleConfigmap (46-46)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: integration
  • GitHub Check: unit
  • GitHub Check: e2e-hosted
  • GitHub Check: verify
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e
🔇 Additional comments (5)
go.mod (1)

43-43: Verify API bump drove CRD/manifests updates (no hand edits).

Please confirm CRD and catalog changes were produced by updating open-cluster-management.io/api and running the standard update targets (e.g., make update/verify). Hand edits in CRD YAMLs are discouraged and get overwritten. Based on learnings.

deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (1)

583-620: Confirm CRD schema updates are vendor-generated.

CRD files here should reflect upstream open-cluster-management.io/api types. Please confirm these loadBalancer/route additions were generated via the normal vendor/update flow, not hand-edited. Based on learnings.

Also applies to: 642-670, 676-679

pkg/operator/helpers/helpers_test.go (1)

2217-2384: LGTM on endpoint type tests.

Covers nil/empty/non‑grpc and specific types cleanly.

manifests/cluster-manager/hub/grpc-server/service.yaml (1)

17-26: Template change looks correct.

Port/type switch matches GRPCEndpointType; targetPort remains 8090.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)

242-253: Good: verify tls.crt and tls.key exist.

This guards secret content, not just presence.

hostNames, grpcErr := helpers.GRPCServerHostNames(c.kubeClient, clustermanagerNamespace, clustermanager)
if grpcErr != nil {
errs = append(errs, grpcErr)
} else if hasRotation(rotations.targetRotations, helpers.GRPCServerSecret) {
Copy link
Member

Choose a reason for hiding this comment

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

could this hasRotation return the rotation so we do not need another for loop?

Copy link
Member

Choose a reason for hiding this comment

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

looking at the code, I think changing targetRotations to a map will make it much simpler.

Copy link
Member Author

Choose a reason for hiding this comment

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

good suggestion. done.

} else if hasRotation(rotations.targetRotations, helpers.GRPCServerSecret) {
for i := range rotations.targetRotations {
if rotations.targetRotations[i].Name == helpers.GRPCServerSecret {
rotations.targetRotations[i].HostNames = hostNames
Copy link
Member

Choose a reason for hiding this comment

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

will grpc server restart if the hostNames changes? having a log output might be helpful here, because here indicates the hostnames is changed.

Copy link
Member Author

Choose a reason for hiding this comment

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

no, I think we need doc this . log is added.

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

🧹 Nitpick comments (2)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1)

825-958: Good coverage of GRPC Service type/port variants; minor optional cleanup

The new TestGRPCServiceLoadBalancerType cleanly validates that:

  • LB endpoint ⇒ Service Type=LoadBalancer, port=443.
  • Hostname / default configs ⇒ Type=ClusterIP, port=8090.

Behavior matches the manifest template and helper wiring.

If you want to trim duplication, consider extracting the “find <name>-grpc-server Service from actions and return its Type/Port” logic into a small helper used by the cases, but that’s purely cosmetic.

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (1)

175-179: GRPC server secret rotation tests are solid and align with new behavior

  • Adding helpers.GRPCServerSecret to the secretInformers maps ensures the controller can watch and manage the new secret alongside the existing ones.
  • In TestCertRotationGRPCAuth, the extra checks that:
    • the GRPC server secret exists (when enabling GRPC) and contains tls.crt / tls.key, and
    • rotationMap[cmName].targetRotations[helpers.GRPCServerSecret] is added/removed appropriately on enable/disable,
      provide good coverage for the new rotation path.

If you’d like broader reuse, you could optionally add helpers.GRPCServerSecret to the secretNames slice so that assertResourcesExistAndValid and assertResourcesNotExist validate this secret as well, but the explicit tests you’ve added already cover the critical behavior.

Also applies to: 242-262, 296-302

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8d5aa0 and da8c83d.

⛔ Files ignored due to path filters (5)
  • go.sum is excluded by !**/*.sum
  • vendor/modules.txt is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/types_clustermanager.go is excluded by !vendor/**
  • vendor/open-cluster-management.io/api/operator/v1/zz_generated.deepcopy.go is excluded by !vendor/**
📒 Files selected for processing (13)
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (2 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml (1 hunks)
  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (2 hunks)
  • go.mod (1 hunks)
  • manifests/cluster-manager/hub/grpc-server/service.yaml (1 hunks)
  • manifests/config.go (1 hunks)
  • pkg/operator/helpers/helpers.go (2 hunks)
  • pkg/operator/helpers/helpers_test.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (5 hunks)
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (5 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1 hunks)
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • manifests/config.go
  • go.mod
  • deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.
📚 Learning: 2025-07-23T10:10:42.066Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1086
File: test/integration/util/grpc.go:146-146
Timestamp: 2025-07-23T10:10:42.066Z
Learning: In OCM codebase, there are two different GRPCServerOptions types: the local one in pkg/server/grpc/options.go (which only has GRPCServerConfig field) and the SDK one from open-cluster-management.io/sdk-go/pkg/cloudevents/server/grpc/options (which has ServerBindPort and other fields with default values). Test code uses the SDK version via grpcoptions import alias.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go
  • pkg/operator/helpers/helpers_test.go
  • manifests/cluster-manager/hub/grpc-server/service.yaml
  • pkg/operator/helpers/helpers.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
📚 Learning: 2025-08-04T08:58:41.865Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: manifests/klusterlet/management/klusterlet-registration-deployment.yaml:111-115
Timestamp: 2025-08-04T08:58:41.865Z
Learning: In OCM klusterlet deployments, gRPC authentication uses different file naming conventions than CSR/kube authentication: gRPC auth expects config.yaml files (/spoke/bootstrap/config.yaml and /spoke/hub-kubeconfig/config.yaml) while CSR/kube auth uses kubeconfig files. The gRPC driver explicitly creates config.yaml files in the secret data via additionalSecretData["config.yaml"] = d.configTemplate.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go
📚 Learning: 2025-07-25T01:21:08.891Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1077
File: test/integration/registration/spokecluster_grpc_test.go:0-0
Timestamp: 2025-07-25T01:21:08.891Z
Learning: In OCM integration tests, gRPC and kube authentication mechanisms require different CSR handling approaches: gRPC authentication uses util.ApproveCSR since the hub controller signs client certificates, while kube authentication uses authn.ApproveSpokeClusterCSR to simulate the kube-controller-manager signing client certificates.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go
📚 Learning: 2025-07-15T06:10:13.001Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1071
File: pkg/server/grpc/clients.go:73-76
Timestamp: 2025-07-15T06:10:13.001Z
Learning: In OCM (Open Cluster Management) gRPC server informer setup, cache sync verification is not necessary when starting informers in the clients.Run() method. The current pattern of starting informers as goroutines without explicit cache sync waiting is the preferred approach for this codebase.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go
📚 Learning: 2025-08-28T01:59:04.611Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml:94-176
Timestamp: 2025-08-28T01:59:04.611Z
Learning: The file deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml is copied from vendor and should not be modified directly as changes would be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:50.021Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:168-175
Timestamp: 2025-08-28T01:58:50.021Z
Learning: In the OCM project, CRD schemas come from the open-cluster-management.io/api dependency. Changes to CRD schemas should be made upstream in that API package, not in the local CRD YAML files which are generated/copied from the API types.

Applied to files:

  • deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml
  • pkg/operator/helpers/helpers.go
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-07-14T09:30:25.378Z
Learnt from: zhujian7
Repo: open-cluster-management-io/ocm PR: 1070
File: SECURITY-INSIGHTS.yml:44-44
Timestamp: 2025-07-14T09:30:25.378Z
Learning: In the open-cluster-management-io/ocm repository, the team prefers to use commit SHAs instead of tags for GitHub Actions dependencies like dependency-review-action for security reasons, as commit SHAs are immutable while tags can be moved.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-07-01T05:27:25.998Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1058
File: pkg/server/services/cluster/cluster.go:48-64
Timestamp: 2025-07-01T05:27:25.998Z
Learning: The ClusterService struct in pkg/server/services/cluster/cluster.go implements the server.Service interface, so method names like List() cannot be renamed as they must match the interface definition exactly.

Applied to files:

  • pkg/operator/helpers/helpers.go
📚 Learning: 2025-10-14T09:37:12.472Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1196
File: pkg/work/spoke/controllers/manifestcontroller/manifestwork_controller.go:231-242
Timestamp: 2025-10-14T09:37:12.472Z
Learning: In the ocm repository, there are two different factory packages with different SyncContext.Queue() return types:
1. `github.com/openshift/library-go/pkg/controller/factory` returns `workqueue.RateLimitingInterface` (non-typed)
2. `open-cluster-management.io/sdk-go/pkg/basecontroller/factory` returns `workqueue.TypedRateLimitingInterface[string]` (typed)

When reviewing controller code, check which factory import is used to determine the correct queue interface type.

Applied to files:

  • pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go
📚 Learning: 2025-08-28T01:58:05.882Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:128-135
Timestamp: 2025-08-28T01:58:05.882Z
Learning: Files in deploy/cluster-manager/chart/cluster-manager/crds/ and similar CRD directories are often copied from vendor/upstream sources and should not be modified directly to avoid conflicts during updates.

Applied to files:

  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:37.933Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:247-280
Timestamp: 2025-08-28T01:58:37.933Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor and should not be modified locally as changes may be overwritten during vendor updates.

Applied to files:

  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T04:09:12.357Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:94-176
Timestamp: 2025-08-28T04:09:12.357Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ directory are copied from vendor/upstream sources and should not be modified directly.

Applied to files:

  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T01:58:23.958Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/cluster-manager/chart/cluster-manager/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml:192-225
Timestamp: 2025-08-28T01:58:23.958Z
Learning: CRD files in deploy/cluster-manager/chart/cluster-manager/crds/ and deploy/cluster-manager/config/crds/ directories are copied from vendor (open-cluster-management.io/api dependency) and should not be modified locally.

Applied to files:

  • deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml
  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-09-16T03:04:38.251Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1158
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:48-48
Timestamp: 2025-09-16T03:04:38.251Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are properly updated via "make update" when vendor dependencies change (like open-cluster-management.io/api updates) and validated by "make verify". The issue is only with local hand-edits, not legitimate vendor update processes.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-06T06:00:53.508Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1107
File: deploy/cluster-manager/config/rbac/cluster_role.yaml:165-168
Timestamp: 2025-08-06T06:00:53.508Z
Learning: In OCM gRPC deployments, both the cluster-manager operator ClusterRole and the gRPC server ClusterRole need "create" permission on "managedclustersets/join" resources for proper bootstrapping of managed clusters.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-10-10T02:50:14.188Z
Learnt from: qiujian16
Repo: open-cluster-management-io/ocm PR: 1204
File: manifests/cluster-manager/hub/crds/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml:88-91
Timestamp: 2025-10-10T02:50:14.188Z
Learning: Kubernetes CustomResourceDefinition (CRD) OpenAPI v3 schema does not support the `deprecated: true` property for individual fields. Field-level deprecation must be documented in the description field only. The formal `deprecated` property is not supported by Kubernetes CRD tooling.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
📚 Learning: 2025-08-28T02:00:03.385Z
Learnt from: skeeey
Repo: open-cluster-management-io/ocm PR: 1146
File: deploy/klusterlet/chart/klusterlet/crds/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml:278-280
Timestamp: 2025-08-28T02:00:03.385Z
Learning: CRD files in deploy/klusterlet/chart/klusterlet/crds/ and similar directories are copied from vendor code and should not be modified locally. Grammar or other issues in these files should be reported upstream to the vendor instead.

Applied to files:

  • deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml
🧬 Code graph analysis (5)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (923-934)
  • GRPCServerEndpointType (999-1014)
pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller_test.go (2)
pkg/operator/helpers/queuekey.go (1)
  • ClusterManagerNamespace (51-56)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
pkg/operator/helpers/helpers_test.go (1)
pkg/operator/helpers/helpers.go (2)
  • GRPCServerHostNames (936-997)
  • GRPCServerEndpointType (999-1014)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (2)
pkg/operator/helpers/queuekey.go (4)
  • GRPCServerSecret (48-48)
  • RegistrationWebhookSecret (40-40)
  • RegistrationWebhookService (41-41)
  • WorkWebhookSecret (42-42)
pkg/operator/helpers/helpers.go (2)
  • GRPCAuthEnabled (923-934)
  • GRPCServerHostNames (936-997)
pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller_test.go (2)
pkg/operator/helpers/queuekey.go (6)
  • GRPCServerSecret (48-48)
  • ClusterManagerNamespace (51-56)
  • SignerSecret (45-45)
  • RegistrationWebhookSecret (40-40)
  • WorkWebhookSecret (42-42)
  • CaBundleConfigmap (46-46)
pkg/common/testing/fake_sync_context.go (1)
  • NewFakeSyncContext (21-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: e2e-singleton
  • GitHub Check: e2e-hosted
  • GitHub Check: e2e
  • GitHub Check: integration
  • GitHub Check: unit
🔇 Additional comments (10)
deploy/cluster-manager/config/crds/0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml (1)

560-682: CRD schema for new GRPC/HTTPS endpoint types looks consistent; confirm it’s generated, not hand‑edited

The added loadBalancer / route blocks under both grpc and https, and the enum extension of type to include hostname, loadBalancer, route, are structurally consistent with the existing hostname schema (same caBundle/host pattern, optional fields, and string enums). I don’t see OpenAPI/CRD issues here.

Given these CRDs are expected to be generated from open-cluster-management.io/api, please double‑check that this file came from a vendor/api bump + make update/make verify, not from manual editing. Otherwise it may be overwritten on the next vendor update. Based on learnings

pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go (1)

233-239: GRPCAuthEnabled / GRPCEndpointType wiring in HubConfig looks correct

The new fields are derived via helpers and only populated when GRPC auth is enabled, which keeps existing behavior for non‑GRPC setups while driving the updated Service template correctly. No functional issues spotted here.

deploy/cluster-manager/olm-catalog/latest/manifests/cluster-manager.clusterserviceversion.yaml (1)

62-62: Metadata timestamp update is fine

The createdAt annotation bump is metadata‑only and doesn’t affect operator behavior. Assuming this CSV is managed by your usual release/bundle tooling, this looks good.

manifests/cluster-manager/hub/grpc-server/service.yaml (1)

15-27: Conditional GRPC Service port/type behavior matches the new endpoint types

Driving port and spec.type off .GRPCEndpointType gives the expected behavior: LoadBalancer with port 443 for LB exposure, and ClusterIP with 8090 for hostname/route/default. Keeping targetPort: 8090 is consistent with the pod listener. No issues from a templating or semantics standpoint.

deploy/cluster-manager/olm-catalog/latest/manifests/operator.open-cluster-management.io_clustermanagers.yaml (1)

560-682: OLM CRD schema updates are consistent; verify they’re generated from the API

The added grpc.loadBalancer / grpc.route and https.loadBalancer / https.route blocks, plus the extended type enums, line up with the main CRD file and the intended new endpoint exposure types. Structurally this looks correct.

Given this OLM CRD manifest is copied from upstream/vendor, please confirm it was regenerated via the open-cluster-management.io/api bump + make update (or equivalent) rather than hand‑edited, so it won’t be lost on the next vendor sync. Based on learnings

pkg/operator/operators/clustermanager/controllers/certrotationcontroller/certrotation_controller.go (1)

6-6: LGTM! Solid refactoring to support dynamic LoadBalancer hostnames.

The switch from slice-based to map-based targetRotations improves lookup efficiency and makes the hostname update logic cleaner. The GRPC hostname resolution now properly detects when LoadBalancer ingress IPs/hostnames change (line 253) and triggers certificate rotation with a helpful warning log (line 256). Error aggregation ensures partial failures don't block other certificate operations.

Also applies to: 61-61, 190-191, 216-269, 272-290

pkg/operator/helpers/helpers.go (2)

936-997: LGTM! Well-structured hostname resolution with proper error handling.

The function correctly resolves gRPC server hostnames from different endpoint types:

  • Default service DNS name (line 937)
  • User-provided hostname (lines 948-952)
  • LoadBalancer host + ingress IPs/hostnames (lines 955-988)

Returning partial hostNames alongside errors (lines 965, 970, 976) is good design—it allows cert rotation to proceed with whatever was successfully resolved. The guards against nil pointers and the deduplication logic using slices.Contains are appropriate.


999-1014: LGTM! Clean endpoint type resolution.

The function provides a straightforward way to determine the gRPC endpoint type, defaulting to Hostname when configuration is missing or incomplete. This aligns with the default behavior in GRPCServerHostNames.

pkg/operator/helpers/helpers_test.go (2)

1880-2258: LGTM! Excellent test coverage for hostname resolution.

The test suite comprehensively covers:

  • Configuration edge cases (nil, empty, non-GRPC endpoints)
  • Hostname endpoint with valid/empty hosts
  • LoadBalancer with IP, hostname, both, and duplicates
  • Error paths (service not found, missing ingress, empty ingress)

The table-driven approach with clear test names makes this maintainable and easy to extend when Route support is added.


2260-2427: LGTM! Thorough endpoint type detection tests.

Tests validate the endpoint type resolution logic across all configuration scenarios, including proper defaulting to Hostname when configuration is absent or incomplete.

signingRotation certrotation.SigningRotation
caBundleRotation certrotation.CABundleRotation
targetRotations []certrotation.TargetRotation
targetRotations map[string]certrotation.TargetRotation
Copy link
Member

Choose a reason for hiding this comment

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

the key should be namespace+name

Copy link
Member Author

Choose a reason for hiding this comment

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

each clusterManager has its own set of rotations , and the namespace is fixed to open-cluster-management-hub in default mode and clustermanager.Name in hosted mode. so I think it is ok to use name as the key .
not sure if there is any other concern about the key ?

Copy link
Member

Choose a reason for hiding this comment

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

ok

@qiujian16
Copy link
Member

/approve
/lgtm

@openshift-ci openshift-ci bot added the lgtm label Nov 19, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 19, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: qiujian16, zhiweiyin318

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

The pull request process is described 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

@openshift-merge-bot openshift-merge-bot bot merged commit 76449f8 into open-cluster-management-io:main Nov 19, 2025
17 checks passed
@zhiweiyin318 zhiweiyin318 deleted the grpc-server-lb branch November 19, 2025 02:52
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.

3 participants