diff --git a/pkg/kubelet/server/auth_test.go b/pkg/kubelet/server/auth_test.go index b6a32bbe68e..a03c0047f92 100644 --- a/pkg/kubelet/server/auth_test.go +++ b/pkg/kubelet/server/auth_test.go @@ -124,6 +124,7 @@ func AuthzTestCases() []AuthzTestCase { "/logs/": "log", "/logs/{logpath:*}": "log", "/metrics": "metrics", + "/metrics/slis": "metrics", "/metrics/cadvisor": "metrics", "/metrics/probes": "metrics", "/metrics/resource": "metrics", diff --git a/pkg/kubelet/server/server_test.go b/pkg/kubelet/server/server_test.go index 5c334eacd6d..a8ba75464ad 100644 --- a/pkg/kubelet/server/server_test.go +++ b/pkg/kubelet/server/server_test.go @@ -1528,3 +1528,19 @@ func TestTrimURLPath(t *testing.T) { assert.Equal(t, test.expected, getURLRootPath(test.path), fmt.Sprintf("path is: %s", test.path)) } } + +func TestNewServerRegistersMetricsSLIsEndpointTwice(t *testing.T) { + host := &fakeKubelet{ + hostnameFunc: func() string { + return "127.0.0.1" + }, + } + resourceAnalyzer := stats.NewResourceAnalyzer(nil, time.Minute, &record.FakeRecorder{}) + + server1 := NewServer(host, resourceAnalyzer, nil, nil) + server2 := NewServer(host, resourceAnalyzer, nil, nil) + + // Check if both servers registered the /metrics/slis endpoint + assert.Contains(t, server1.restfulCont.RegisteredHandlePaths(), "/metrics/slis", "First server should register /metrics/slis") + assert.Contains(t, server2.restfulCont.RegisteredHandlePaths(), "/metrics/slis", "Second server should register /metrics/slis") +} diff --git a/staging/src/k8s.io/component-base/metrics/prometheus/slis/routes.go b/staging/src/k8s.io/component-base/metrics/prometheus/slis/routes.go index 4e88b7c24a0..a88607fa500 100644 --- a/staging/src/k8s.io/component-base/metrics/prometheus/slis/routes.go +++ b/staging/src/k8s.io/component-base/metrics/prometheus/slis/routes.go @@ -38,8 +38,8 @@ type SLIMetrics struct{} func (s SLIMetrics) Install(m mux) { installOnce.Do(func() { Register(Registry) - m.Handle("/metrics/slis", metrics.HandlerFor(Registry, metrics.HandlerOpts{})) }) + m.Handle("/metrics/slis", metrics.HandlerFor(Registry, metrics.HandlerOpts{})) } type SLIMetricsWithReset struct{} @@ -48,6 +48,6 @@ type SLIMetricsWithReset struct{} func (s SLIMetricsWithReset) Install(m mux) { installWithResetOnce.Do(func() { Register(Registry) - m.Handle("/metrics/slis", metrics.HandlerWithReset(Registry, metrics.HandlerOpts{})) }) + m.Handle("/metrics/slis", metrics.HandlerWithReset(Registry, metrics.HandlerOpts{})) } diff --git a/staging/src/k8s.io/component-base/metrics/prometheus/slis/routes_test.go b/staging/src/k8s.io/component-base/metrics/prometheus/slis/routes_test.go new file mode 100644 index 00000000000..b045f04b065 --- /dev/null +++ b/staging/src/k8s.io/component-base/metrics/prometheus/slis/routes_test.go @@ -0,0 +1,44 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package slis + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +type mockMux struct { + handledPaths []string +} + +func (m *mockMux) Handle(path string, handler http.Handler) { + m.handledPaths = append(m.handledPaths, path) +} + +func TestSLIMetrics_Install(t *testing.T) { + m := &mockMux{} + s := SLIMetrics{} + + s.Install(m) + assert.Equal(t, []string{"/metrics/slis"}, m.handledPaths) + + s.Install(m) + // Assert that the path is registered twice for the 2 calls made to Install(). + assert.Equal(t, []string{"/metrics/slis", "/metrics/slis"}, m.handledPaths, "Should handle the path twice.") +}