From 707e294fecaae47074b37a73640b9692e4c496c0 Mon Sep 17 00:00:00 2001 From: Haoran Wang Date: Thu, 11 Jun 2026 19:17:22 +1000 Subject: [PATCH] fix: apply MetricsSet relabel configs to KAS ServiceMonitor The KAS adaptServiceMonitor() function was missing the line that applies MetricRelabelConfigs from the configured MetricsSet (Telemetry/SRE/All). Every other component (etcd, KCM, CVO, scheduler, OAPI, OCM, routecm, NTO, OLM, catalog-operator) correctly calls its corresponding metrics.XxxRelabelConfigs(cpContext.MetricsSet), but KAS did not. This caused the KAS ServiceMonitor to always use the hardcoded Telemetry default from the YAML asset (3 metrics: apiserver_storage_objects, apiserver_request_total, apiserver_current_inflight_requests), ignoring the sre-metric-set ConfigMap entirely when METRICS_SET=SRE. The fix adds the missing call to metrics.KASRelabelConfigs() and a unit test matching the pattern used by KCM (kcm/servicemonitor_test.go). --- ...ponents_kube_apiserver_servicemonitor.yaml | 45 +++++- ...ponents_kube_apiserver_servicemonitor.yaml | 45 +++++- ...ponents_kube_apiserver_servicemonitor.yaml | 45 +++++- ...ponents_kube_apiserver_servicemonitor.yaml | 45 +++++- ...ponents_kube_apiserver_servicemonitor.yaml | 45 +++++- .../v2/kas/servicemonitor.go | 2 + .../v2/kas/servicemonitor_test.go | 136 ++++++++++++++++++ 7 files changed, 353 insertions(+), 10 deletions(-) create mode 100644 control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor_test.go diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml index 2a9605902e83..76077e0e3314 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml +++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/AROSwift/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml @@ -19,10 +19,51 @@ metadata: spec: endpoints: - metricRelabelings: - - action: keep - regex: (apiserver_storage_objects|apiserver_request_total|apiserver_current_inflight_requests) + - action: drop + regex: etcd_(debugging|disk|server).* sourceLabels: - __name__ + - action: drop + regex: apiserver_admission_controller_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: apiserver_admission_step_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs) + sourceLabels: + - __name__ + - action: drop + regex: docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: network_plugin_operations_latency_microseconds|sync_proxy_rules_latency_microseconds|rest_client_request_latency_seconds + sourceLabels: + - __name__ + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50)(\.0)? + sourceLabels: + - __name__ + - le - action: replace replacement: "" targetLabel: _id diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/GCP/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/GCP/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml index 2a9605902e83..76077e0e3314 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/GCP/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml +++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/GCP/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml @@ -19,10 +19,51 @@ metadata: spec: endpoints: - metricRelabelings: - - action: keep - regex: (apiserver_storage_objects|apiserver_request_total|apiserver_current_inflight_requests) + - action: drop + regex: etcd_(debugging|disk|server).* sourceLabels: - __name__ + - action: drop + regex: apiserver_admission_controller_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: apiserver_admission_step_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs) + sourceLabels: + - __name__ + - action: drop + regex: docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: network_plugin_operations_latency_microseconds|sync_proxy_rules_latency_microseconds|rest_client_request_latency_seconds + sourceLabels: + - __name__ + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50)(\.0)? + sourceLabels: + - __name__ + - le - action: replace replacement: "" targetLabel: _id diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml index 2a9605902e83..76077e0e3314 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml +++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/IBMCloud/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml @@ -19,10 +19,51 @@ metadata: spec: endpoints: - metricRelabelings: - - action: keep - regex: (apiserver_storage_objects|apiserver_request_total|apiserver_current_inflight_requests) + - action: drop + regex: etcd_(debugging|disk|server).* sourceLabels: - __name__ + - action: drop + regex: apiserver_admission_controller_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: apiserver_admission_step_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs) + sourceLabels: + - __name__ + - action: drop + regex: docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: network_plugin_operations_latency_microseconds|sync_proxy_rules_latency_microseconds|rest_client_request_latency_seconds + sourceLabels: + - __name__ + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50)(\.0)? + sourceLabels: + - __name__ + - le - action: replace replacement: "" targetLabel: _id diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml index 2a9605902e83..76077e0e3314 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml +++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/TechPreviewNoUpgrade/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml @@ -19,10 +19,51 @@ metadata: spec: endpoints: - metricRelabelings: - - action: keep - regex: (apiserver_storage_objects|apiserver_request_total|apiserver_current_inflight_requests) + - action: drop + regex: etcd_(debugging|disk|server).* sourceLabels: - __name__ + - action: drop + regex: apiserver_admission_controller_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: apiserver_admission_step_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs) + sourceLabels: + - __name__ + - action: drop + regex: docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: network_plugin_operations_latency_microseconds|sync_proxy_rules_latency_microseconds|rest_client_request_latency_seconds + sourceLabels: + - __name__ + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50)(\.0)? + sourceLabels: + - __name__ + - le - action: replace replacement: "" targetLabel: _id diff --git a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml index 2a9605902e83..76077e0e3314 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml +++ b/control-plane-operator/controllers/hostedcontrolplane/testdata/kube-apiserver/zz_fixture_TestControlPlaneComponents_kube_apiserver_servicemonitor.yaml @@ -19,10 +19,51 @@ metadata: spec: endpoints: - metricRelabelings: - - action: keep - regex: (apiserver_storage_objects|apiserver_request_total|apiserver_current_inflight_requests) + - action: drop + regex: etcd_(debugging|disk|server).* sourceLabels: - __name__ + - action: drop + regex: apiserver_admission_controller_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: apiserver_admission_step_admission_latencies_seconds_.* + sourceLabels: + - __name__ + - action: drop + regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds) + sourceLabels: + - __name__ + - action: drop + regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs) + sourceLabels: + - __name__ + - action: drop + regex: docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout) + sourceLabels: + - __name__ + - action: drop + regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total) + sourceLabels: + - __name__ + - action: drop + regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary) + sourceLabels: + - __name__ + - action: drop + regex: transformation_(transformation_latencies_microseconds|failures_total) + sourceLabels: + - __name__ + - action: drop + regex: network_plugin_operations_latency_microseconds|sync_proxy_rules_latency_microseconds|rest_client_request_latency_seconds + sourceLabels: + - __name__ + - action: drop + regex: apiserver_request_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50)(\.0)? + sourceLabels: + - __name__ + - le - action: replace replacement: "" targetLabel: _id diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor.go index fc8d498eae86..239c9e51428c 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor.go @@ -4,6 +4,7 @@ import ( _ "embed" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/metrics" "github.com/openshift/hypershift/support/util" prometheusoperatorv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" @@ -13,6 +14,7 @@ func adaptServiceMonitor(cpContext component.WorkloadContext, sm *prometheusoper sm.Spec.NamespaceSelector = prometheusoperatorv1.NamespaceSelector{ MatchNames: []string{cpContext.HCP.Namespace}, } + sm.Spec.Endpoints[0].MetricRelabelConfigs = metrics.KASRelabelConfigs(cpContext.MetricsSet) util.ApplyClusterIDLabel(&sm.Spec.Endpoints[0], cpContext.HCP.Spec.ClusterID) return nil diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor_test.go new file mode 100644 index 000000000000..97f6c0f2aa38 --- /dev/null +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/servicemonitor_test.go @@ -0,0 +1,136 @@ +package kas + +import ( + "testing" + + . "github.com/onsi/gomega" + + hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" + component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/metrics" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + prometheusoperatorv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" +) + +func TestAdaptServiceMonitor(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + metricsSet metrics.MetricsSet + clusterID string + validate func(*testing.T, *prometheusoperatorv1.ServiceMonitor, error) + }{ + { + name: "When service monitor is adapted, it should set namespace selector", + metricsSet: metrics.MetricsSetTelemetry, + clusterID: "test-cluster-id", + validate: func(t *testing.T, sm *prometheusoperatorv1.ServiceMonitor, err error) { + g := NewWithT(t) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(sm.Spec.NamespaceSelector.MatchNames).To(Equal([]string{"test-namespace"})) + }, + }, + { + name: "When metrics set is Telemetry, it should apply Telemetry relabel configs", + metricsSet: metrics.MetricsSetTelemetry, + clusterID: "test-cluster-id", + validate: func(t *testing.T, sm *prometheusoperatorv1.ServiceMonitor, err error) { + g := NewWithT(t) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(sm.Spec.Endpoints).To(HaveLen(1)) + + // Telemetry set produces 1 keep rule + 1 cluster ID relabel = 2 MetricRelabelConfigs + g.Expect(sm.Spec.Endpoints[0].MetricRelabelConfigs).To(HaveLen(2)) + g.Expect(string(sm.Spec.Endpoints[0].MetricRelabelConfigs[0].Action)).To(Equal("keep")) + g.Expect(sm.Spec.Endpoints[0].MetricRelabelConfigs[0].Regex).To(Equal("(apiserver_storage_objects|apiserver_request_total|apiserver_current_inflight_requests)")) + }, + }, + { + name: "When service monitor is adapted, it should apply cluster ID label in both RelabelConfigs and MetricRelabelConfigs", + metricsSet: metrics.MetricsSetTelemetry, + clusterID: "cluster-abc-123", + validate: func(t *testing.T, sm *prometheusoperatorv1.ServiceMonitor, err error) { + g := NewWithT(t) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(sm.Spec.Endpoints).To(HaveLen(1)) + + // Check cluster ID in RelabelConfigs + foundInRelabel := false + for _, config := range sm.Spec.Endpoints[0].RelabelConfigs { + if config.TargetLabel == "_id" && config.Replacement != nil && *config.Replacement == "cluster-abc-123" { + foundInRelabel = true + break + } + } + g.Expect(foundInRelabel).To(BeTrue(), "cluster ID label should be applied in RelabelConfigs") + + // Check cluster ID in MetricRelabelConfigs + foundInMetricRelabel := false + for _, config := range sm.Spec.Endpoints[0].MetricRelabelConfigs { + if config.TargetLabel == "_id" && config.Replacement != nil && *config.Replacement == "cluster-abc-123" { + foundInMetricRelabel = true + break + } + } + g.Expect(foundInMetricRelabel).To(BeTrue(), "cluster ID label should be applied in MetricRelabelConfigs") + }, + }, + { + name: "When metrics set is SRE with no config loaded, MetricRelabelConfigs should only contain cluster ID", + metricsSet: metrics.MetricsSetSRE, + clusterID: "test-cluster", + validate: func(t *testing.T, sm *prometheusoperatorv1.ServiceMonitor, err error) { + g := NewWithT(t) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(sm.Spec.Endpoints).To(HaveLen(1)) + + // KASRelabelConfigs(SRE) returns nil when no SRE config is loaded, + // so MetricRelabelConfigs only contains the cluster ID entry from ApplyClusterIDLabel. + g.Expect(sm.Spec.Endpoints[0].MetricRelabelConfigs).To(HaveLen(1)) + g.Expect(sm.Spec.Endpoints[0].MetricRelabelConfigs[0].TargetLabel).To(Equal("_id")) + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + hcp := &hyperv1.HostedControlPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-hcp", + Namespace: "test-namespace", + }, + Spec: hyperv1.HostedControlPlaneSpec{ + ClusterID: tc.clusterID, + }, + } + + cpContext := component.WorkloadContext{ + Context: t.Context(), + HCP: hcp, + MetricsSet: tc.metricsSet, + } + + sm := &prometheusoperatorv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kube-apiserver", + Namespace: "test-namespace", + }, + Spec: prometheusoperatorv1.ServiceMonitorSpec{ + Endpoints: []prometheusoperatorv1.Endpoint{ + { + Port: "client", + }, + }, + }, + } + + err := adaptServiceMonitor(cpContext, sm) + tc.validate(t, sm, err) + }) + } +}