Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions pkg/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options) error {
)
}

telemetryMux := buildTelemetryServer(ksmMetricsRegistry, opts.AuthFilter, kubeConfig)
telemetryMux := buildTelemetryServer(ksmMetricsRegistry, opts.AuthFilter, kubeConfig, web.NewLandingPage)
telemetryListenAddress := net.JoinHostPort(opts.TelemetryHost, strconv.Itoa(opts.TelemetryPort))
telemetryServer := http.Server{
Handler: telemetryMux,
Expand All @@ -356,7 +356,7 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options) error {
WebConfigFile: &tlsConfig,
}

metricsMux := buildMetricsServer(m, durationVec, kubeClient, opts.AuthFilter, kubeConfig)
metricsMux := buildMetricsServer(m, durationVec, kubeClient, opts.AuthFilter, kubeConfig, web.NewLandingPage)
metricsServerListenAddress := net.JoinHostPort(opts.Host, strconv.Itoa(opts.Port))
metricsServer := http.Server{
Handler: metricsMux,
Expand Down Expand Up @@ -457,7 +457,7 @@ func configureResourcesAndMetrics(opts *options.Options, configFile []byte) *opt
return opts
}

func buildTelemetryServer(registry prometheus.Gatherer, authFilter bool, kubeConfig *rest.Config) *http.ServeMux {
func buildTelemetryServer(registry prometheus.Gatherer, authFilter bool, kubeConfig *rest.Config, newLandingPage func(web.LandingConfig) (*web.LandingPageHandler, error)) *http.ServeMux {
Comment thread
carterpewpew marked this conversation as resolved.
mux := http.NewServeMux()

loghandler := logr.ToSlogHandler(klog.Background())
Expand Down Expand Up @@ -510,9 +510,10 @@ func buildTelemetryServer(registry prometheus.Gatherer, authFilter bool, kubeCon
},
},
}
landingPage, err := web.NewLandingPage(landingConfig)
landingPage, err := newLandingPage(landingConfig)
if err != nil {
klog.ErrorS(err, "failed to create landing page")
return mux
}
mux.Handle("/", landingPage)
return mux
Expand All @@ -534,7 +535,7 @@ func handleClusterDelegationForProber(client kubernetes.Interface, probeType str
}
}

func buildMetricsServer(m *metricshandler.MetricsHandler, durationObserver prometheus.ObserverVec, client kubernetes.Interface, authFilter bool, kubeConfig *rest.Config) *http.ServeMux {
func buildMetricsServer(m *metricshandler.MetricsHandler, durationObserver prometheus.ObserverVec, client kubernetes.Interface, authFilter bool, kubeConfig *rest.Config, newLandingPage func(web.LandingConfig) (*web.LandingPageHandler, error)) *http.ServeMux {
mux := http.NewServeMux()

// TODO: This doesn't belong into serveMetrics
Expand Down Expand Up @@ -598,9 +599,10 @@ func buildMetricsServer(m *metricshandler.MetricsHandler, durationObserver prome
},
},
}
landingPage, err := web.NewLandingPage(landingConfig)
landingPage, err := newLandingPage(landingConfig)
if err != nil {
klog.ErrorS(err, "failed to create landing page")
return mux
}
mux.Handle("/", landingPage)
return mux
Expand Down
101 changes: 100 additions & 1 deletion pkg/app/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"flag"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
Expand All @@ -34,6 +35,7 @@
"k8s.io/kube-state-metrics/v2/pkg/optin"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/exporter-toolkit/web"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -395,7 +397,7 @@
}
}

telemetryMux := buildTelemetryServer(reg, false, nil)
telemetryMux := buildTelemetryServer(reg, false, nil, web.NewLandingPage)

req2 := httptest.NewRequest("GET", "http://localhost:8081/metrics", nil)

Expand Down Expand Up @@ -469,7 +471,7 @@
unshardedBuilder := store.NewBuilder()
unshardedBuilder.WithMetrics(reg)
err = unshardedBuilder.WithEnabledResources(options.DefaultResources.AsSlice())
if err != nil {

Check failure on line 474 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-benchmark-tests

not enough arguments in call to buildTelemetryServer

Check failure on line 474 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-unit-tests

not enough arguments in call to buildTelemetryServer

Check failure on line 474 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-benchmark-tests-releasebranch

not enough arguments in call to buildTelemetryServer

Check failure on line 474 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-go-lint

not enough arguments in call to buildTelemetryServer
t.Fatal(err)
}
unshardedBuilder.WithKubeClient(kubeClient)
Expand All @@ -484,7 +486,7 @@
regShard1 := prometheus.NewRegistry()
shardedBuilder1 := store.NewBuilder()
shardedBuilder1.WithMetrics(regShard1)
err = shardedBuilder1.WithEnabledResources(options.DefaultResources.AsSlice())

Check failure on line 489 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-benchmark-tests

not enough arguments in call to buildMetricsServer

Check failure on line 489 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-unit-tests

not enough arguments in call to buildMetricsServer

Check failure on line 489 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-benchmark-tests-releasebranch

not enough arguments in call to buildMetricsServer

Check failure on line 489 in pkg/app/server_test.go

View workflow job for this annotation

GitHub Actions / ci-go-lint

not enough arguments in call to buildMetricsServer
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -987,6 +989,103 @@
},
}
}

func failingLandingPage(_ web.LandingConfig) (*web.LandingPageHandler, error) {
return nil, fmt.Errorf("injected landing page error")
}

func TestBuildTelemetryServerLandingPage(t *testing.T) {
t.Parallel()
reg := prometheus.NewRegistry()
mux := buildTelemetryServer(reg, false, nil, web.NewLandingPage)

req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)

if w.Code != http.StatusOK {
t.Fatalf("expected 200 for landing page at /, got %d", w.Code)
}
}

func TestBuildTelemetryServerLandingPageError(t *testing.T) {
t.Parallel()
reg := prometheus.NewRegistry()
mux := buildTelemetryServer(reg, false, nil, failingLandingPage)

req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)

if w.Code != http.StatusNotFound {
t.Fatalf("expected 404 for / when landing page creation fails, got %d", w.Code)
}

req = httptest.NewRequest("GET", "/metrics", nil)
w = httptest.NewRecorder()
mux.ServeHTTP(w, req)

if w.Code != http.StatusOK {
t.Fatalf("expected 200 for /metrics even when landing page fails, got %d", w.Code)
}
}

func TestBuildMetricsServerLandingPage(t *testing.T) {
t.Parallel()
kubeClient := fake.NewSimpleClientset()

durationVec := prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
ConstLabels: prometheus.Labels{"handler": "metrics"},
}, []string{"method"})

builder := store.NewBuilder()
builder.WithMetrics(prometheus.NewRegistry())
handler := metricshandler.New(&options.Options{}, kubeClient, builder, false)

mux := buildMetricsServer(handler, durationVec, kubeClient, false, nil, web.NewLandingPage)

req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)

if w.Code != http.StatusOK {
t.Fatalf("expected 200 for landing page at /, got %d", w.Code)
}
}

func TestBuildMetricsServerLandingPageError(t *testing.T) {
t.Parallel()
kubeClient := fake.NewSimpleClientset()

durationVec := prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
ConstLabels: prometheus.Labels{"handler": "metrics"},
}, []string{"method"})

builder := store.NewBuilder()
builder.WithMetrics(prometheus.NewRegistry())
handler := metricshandler.New(&options.Options{}, kubeClient, builder, false)

Comment thread
carterpewpew marked this conversation as resolved.
mux := buildMetricsServer(handler, durationVec, kubeClient, false, nil, failingLandingPage)

req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)

if w.Code != http.StatusNotFound {
t.Fatalf("expected 404 for / when landing page creation fails, got %d", w.Code)
}

req = httptest.NewRequest("GET", "/healthz", nil)
w = httptest.NewRecorder()
mux.ServeHTTP(w, req)

if w.Code != http.StatusOK {
t.Fatalf("expected 200 for /healthz even when landing page fails, got %d", w.Code)
}
}

func TestConfigureResourcesAndMetrics(t *testing.T) {
// Prepare a config file in YAML format
configYAML := `
Expand Down
Loading