Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 07ee182

Browse files
itssimrankk8s-publishing-bot
authored andcommitted
List available endpoints for kube-apiserver (#132581)
Fix tests and formatting Use ListedPaths for finding useful endpoints Fix maps import Update dependencies Fix lint Add option to pass listedpaths Remove apiserver component check Install statuz in genericapiserver Register zpagesfeatures Fix import order Avoid adding non-debugging endpoints Fix tests Fix tests fix tests Sort paths Sort in-place Copy paths before sorting Fix string initialization Move sorting to later stage Fix imports Kubernetes-commit: c7d6c09683344d6dacbe5ba3383a8217c1d4ccd7
1 parent 4e07767 commit 07ee182

File tree

5 files changed

+124
-15
lines changed

5 files changed

+124
-15
lines changed

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ require (
2828
go.uber.org/zap v1.27.0
2929
go.yaml.in/yaml/v2 v2.4.2
3030
golang.org/x/sys v0.31.0
31-
k8s.io/apimachinery v0.0.0-20250717170243-9b71f293aa0c
32-
k8s.io/client-go v0.0.0-20250717170920-715e46ed5728
31+
k8s.io/apimachinery v0.0.0-20250723005633-58c4eb072ebf
32+
k8s.io/client-go v0.0.0-20250724024901-5f1f878e5cd4
3333
k8s.io/klog/v2 v2.130.1
3434
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
3535
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8
@@ -80,7 +80,7 @@ require (
8080
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
8181
gopkg.in/inf.v0 v0.9.1 // indirect
8282
gopkg.in/yaml.v3 v3.0.1 // indirect
83-
k8s.io/api v0.0.0-20250717170527-b7a83e2941aa // indirect
83+
k8s.io/api v0.0.0-20250724064529-b87ac725dbf9 // indirect
8484
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
8585
sigs.k8s.io/randfill v1.0.0 // indirect
8686
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,12 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
210210
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
211211
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
212212
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
213-
k8s.io/api v0.0.0-20250717170527-b7a83e2941aa h1:9T75LAFccLxRh1V7SjtTxnpY9H4DoTlajvyLQQuViZg=
214-
k8s.io/api v0.0.0-20250717170527-b7a83e2941aa/go.mod h1:KToU1jTzT+gkd8q+fEft6oTAtPXK9a4pXEqdI6xhoLE=
215-
k8s.io/apimachinery v0.0.0-20250717170243-9b71f293aa0c h1:NoUgdWNyboxIpLhCjKQrm/sGuLKjEYyNf+K4eioV6s8=
216-
k8s.io/apimachinery v0.0.0-20250717170243-9b71f293aa0c/go.mod h1:v1p1Jsze3IHLy5gU17yVqR2qLO7jgYeX6mw3HZy2AEU=
217-
k8s.io/client-go v0.0.0-20250717170920-715e46ed5728 h1:RCOjgxJWj3E8V4gSUuuSaBPlOz8gpqoZsSA5PUUQvHM=
218-
k8s.io/client-go v0.0.0-20250717170920-715e46ed5728/go.mod h1:OVZIe2J7VRQKdzsLDwmqAQyKxd1CKuTEVR7jW9uca2g=
213+
k8s.io/api v0.0.0-20250724064529-b87ac725dbf9 h1:szZeh22FWBBbJjDCHrh8P35J6afaiuPOpaTsgaEyX4Q=
214+
k8s.io/api v0.0.0-20250724064529-b87ac725dbf9/go.mod h1:70o+sJgHYrO2nPMKeEsmpidpEUMobuxHMhjK/ud9+og=
215+
k8s.io/apimachinery v0.0.0-20250723005633-58c4eb072ebf h1:R1l0xAevbhH2Bg0iJuabo8/i9m31D1ehh2ZJPFKh9bc=
216+
k8s.io/apimachinery v0.0.0-20250723005633-58c4eb072ebf/go.mod h1:v1p1Jsze3IHLy5gU17yVqR2qLO7jgYeX6mw3HZy2AEU=
217+
k8s.io/client-go v0.0.0-20250724024901-5f1f878e5cd4 h1:cUaPGCS7dfX5d85Q8ZJBD2rdK5C6tbWEtGFdBcH+bxo=
218+
k8s.io/client-go v0.0.0-20250724024901-5f1f878e5cd4/go.mod h1:kgDY5crqhNpktphA+cjWLcLLjrF5apg7TWTtaVyhUm8=
219219
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
220220
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
221221
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=

zpages/statusz/registry.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,25 @@ type statuszRegistry interface {
3232
goVersion() string
3333
binaryVersion() *version.Version
3434
emulationVersion() *version.Version
35+
paths() []string
3536
}
3637

3738
type registry struct {
3839
// componentGlobalsRegistry compatibility.ComponentGlobalsRegistry
3940
effectiveVersion compatibility.EffectiveVersion
41+
// listedPaths is an alphabetically sorted list of paths to be reported at /.
42+
listedPaths []string
43+
}
44+
45+
// Option is a function to configure registry.
46+
type Option func(reg *registry)
47+
48+
// WithListedPaths returns an Option to configure the ListedPaths.
49+
func WithListedPaths(listedPaths []string) Option {
50+
cpyListedPaths := make([]string, len(listedPaths))
51+
copy(cpyListedPaths, listedPaths)
52+
53+
return func(reg *registry) { reg.listedPaths = cpyListedPaths }
4054
}
4155

4256
func (*registry) processStartTime() time.Time {
@@ -66,3 +80,11 @@ func (r *registry) emulationVersion() *version.Version {
6680

6781
return nil
6882
}
83+
84+
func (r *registry) paths() []string {
85+
if r.listedPaths != nil {
86+
return r.listedPaths
87+
}
88+
89+
return nil
90+
}

zpages/statusz/statusz.go

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"html"
2222
"math/rand"
2323
"net/http"
24+
"sort"
25+
"strings"
2426
"time"
2527

2628
"k8s.io/component-base/compatibility"
@@ -29,7 +31,14 @@ import (
2931
)
3032

3133
var (
32-
delimiters = []string{":", ": ", "=", " "}
34+
delimiters = []string{":", ": ", "=", " "}
35+
nonDebuggingEndpoints = map[string]bool{
36+
"/apis": true,
37+
"/api": true,
38+
"/openid": true,
39+
"/openapi": true,
40+
"/.well-known": true,
41+
}
3342
)
3443

3544
const DefaultStatuszPath = "/statusz"
@@ -43,8 +52,15 @@ type mux interface {
4352
Handle(path string, handler http.Handler)
4453
}
4554

46-
func NewRegistry(effectiveVersion compatibility.EffectiveVersion) statuszRegistry {
47-
return &registry{effectiveVersion: effectiveVersion}
55+
type ListedPathsOption []string
56+
57+
func NewRegistry(effectiveVersion compatibility.EffectiveVersion, opts ...func(*registry)) statuszRegistry {
58+
r := &registry{effectiveVersion: effectiveVersion}
59+
for _, opt := range opts {
60+
opt(r)
61+
}
62+
63+
return r
4864
}
4965

5066
func Install(m mux, componentName string, reg statuszRegistry) {
@@ -59,7 +75,7 @@ func handleStatusz(componentName string, reg statuszRegistry) http.HandlerFunc {
5975
}
6076

6177
fmt.Fprintf(w, headerFmt, componentName)
62-
data, err := populateStatuszData(reg)
78+
data, err := populateStatuszData(reg, componentName)
6379
if err != nil {
6480
klog.Errorf("error while populating statusz data: %v", err)
6581
http.Error(w, "error while populating statusz data", http.StatusInternalServerError)
@@ -71,7 +87,7 @@ func handleStatusz(componentName string, reg statuszRegistry) http.HandlerFunc {
7187
}
7288
}
7389

74-
func populateStatuszData(reg statuszRegistry) (string, error) {
90+
func populateStatuszData(reg statuszRegistry, componentName string) (string, error) {
7591
randomIndex := rand.Intn(len(delimiters))
7692
delim := html.EscapeString(delimiters[randomIndex])
7793
startTime := html.EscapeString(reg.processStartTime().Format(time.UnixDate))
@@ -83,14 +99,19 @@ func populateStatuszData(reg statuszRegistry) (string, error) {
8399
if reg.emulationVersion() != nil {
84100
emulationVersion = fmt.Sprintf(`Emulation version%s %s`, delim, html.EscapeString(reg.emulationVersion().String()))
85101
}
102+
paths := aggregatePaths(reg.paths())
103+
if paths != "" {
104+
paths = fmt.Sprintf(`Paths%s %s`, delim, html.EscapeString(paths))
105+
}
86106

87107
status := fmt.Sprintf(`
88108
Started%[1]s %[2]s
89109
Up%[1]s %[3]s
90110
Go version%[1]s %[4]s
91111
Binary version%[1]s %[5]s
92112
%[6]s
93-
`, delim, startTime, uptime, goVersion, binaryVersion, emulationVersion)
113+
%[7]s
114+
`, delim, startTime, uptime, goVersion, binaryVersion, emulationVersion, paths)
94115

95116
return status, nil
96117
}
@@ -100,3 +121,26 @@ func uptime(t time.Time) string {
100121
return fmt.Sprintf("%d hr %02d min %02d sec",
101122
upSince/3600, (upSince/60)%60, upSince%60)
102123
}
124+
125+
func aggregatePaths(listedPaths []string) string {
126+
paths := make(map[string]bool)
127+
for _, listedPath := range listedPaths {
128+
folder := "/" + strings.Split(listedPath, "/")[1]
129+
if !paths[folder] && !nonDebuggingEndpoints[folder] {
130+
paths[folder] = true
131+
}
132+
}
133+
134+
var sortedPaths []string
135+
for p := range paths {
136+
sortedPaths = append(sortedPaths, p)
137+
}
138+
sort.Strings(sortedPaths)
139+
140+
var path string
141+
for _, p := range sortedPaths {
142+
path += " " + p
143+
}
144+
145+
return path
146+
}

zpages/statusz/statusz_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Up: %s
3636
Go version: %s
3737
Binary version: %v
3838
Emulation version: %v
39+
Paths: /livez /readyz
3940
`
4041

4142
const wantTmplWithoutEmulation = `
@@ -47,6 +48,19 @@ Up: %s
4748
Go version: %s
4849
Binary version: %v
4950
51+
Paths: /livez /readyz
52+
`
53+
54+
const wantTmplWithKubeApiserverComp = `
55+
%s statusz
56+
Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only.
57+
58+
Started: %v
59+
Up: %s
60+
Go version: %s
61+
Binary version: %v
62+
63+
Paths: /livez /readyz
5064
`
5165

5266
func TestStatusz(t *testing.T) {
@@ -58,6 +72,7 @@ func TestStatusz(t *testing.T) {
5872
fakeEvStr := "1.30"
5973
fakeBinaryVersion := parseVersion(t, fakeBvStr)
6074
fakeEmulationVersion := parseVersion(t, fakeEvStr)
75+
fakeListedPaths := []string{"/livez/poststarthook/peer-discovery-cache-sync", "/livez/post", "/readyz/informer-sync", "/readyz/log", "/readyz/ping"}
6176
tests := []struct {
6277
name string
6378
componentName string
@@ -80,6 +95,7 @@ func TestStatusz(t *testing.T) {
8095
goVer: fakeGoVersion,
8196
binaryVer: fakeBinaryVersion,
8297
emulationVer: fakeEmulationVersion,
98+
listedPaths: fakeListedPaths,
8399
},
84100
wantStatusCode: http.StatusOK,
85101
wantBody: fmt.Sprintf(
@@ -101,6 +117,7 @@ func TestStatusz(t *testing.T) {
101117
goVer: fakeGoVersion,
102118
binaryVer: fakeBinaryVersion,
103119
emulationVer: nil,
120+
listedPaths: fakeListedPaths,
104121
},
105122
wantStatusCode: http.StatusOK,
106123
wantBody: fmt.Sprintf(
@@ -112,6 +129,27 @@ func TestStatusz(t *testing.T) {
112129
fakeBinaryVersion,
113130
),
114131
},
132+
{
133+
name: "valid request for kube-apiserver",
134+
componentName: "kube-apiserver",
135+
reqHeader: "text/plain; charset=utf-8",
136+
registry: fakeRegistry{
137+
startTime: fakeStartTime,
138+
goVer: fakeGoVersion,
139+
binaryVer: fakeBinaryVersion,
140+
emulationVer: nil,
141+
listedPaths: fakeListedPaths,
142+
},
143+
wantStatusCode: http.StatusOK,
144+
wantBody: fmt.Sprintf(
145+
wantTmplWithKubeApiserverComp,
146+
"kube-apiserver",
147+
fakeStartTime.Format(time.UnixDate),
148+
fakeUptime,
149+
fakeGoVersion,
150+
fakeBinaryVersion,
151+
),
152+
},
115153
}
116154

117155
for _, tt := range tests {
@@ -166,6 +204,7 @@ type fakeRegistry struct {
166204
goVer string
167205
binaryVer *version.Version
168206
emulationVer *version.Version
207+
listedPaths []string
169208
}
170209

171210
func (f fakeRegistry) processStartTime() time.Time {
@@ -183,3 +222,7 @@ func (f fakeRegistry) binaryVersion() *version.Version {
183222
func (f fakeRegistry) emulationVersion() *version.Version {
184223
return f.emulationVer
185224
}
225+
226+
func (f fakeRegistry) paths() []string {
227+
return f.listedPaths
228+
}

0 commit comments

Comments
 (0)