Skip to content

Commit d8fbc52

Browse files
committed
Fix handler panic when bootstrapper returned empty peer list
Panic gets rescued by the http server, and was only visible when running in debug mode, but should be handled properly. Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
1 parent bb3b133 commit d8fbc52

5 files changed

Lines changed: 18 additions & 9 deletions

File tree

pkg/agent/https/https.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func Start(ctx context.Context, nodeConfig *config.Node, runtime *config.Control
5656
runtime.Handler = router
5757
}
5858

59-
router.Use(auth.Delegated(nodeConfig.AgentConfig.ClientCA, nodeConfig.AgentConfig.KubeConfigKubelet, config))
59+
router.Use(auth.RequestInfo(), auth.Delegated(nodeConfig.AgentConfig.ClientCA, nodeConfig.AgentConfig.KubeConfigKubelet, config))
6060

6161
if config.SecureServing != nil {
6262
_, _, err = config.SecureServing.Serve(router, 0, ctx.Done())

pkg/server/auth/auth.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,19 +124,23 @@ func Delegated(clientCA, kubeConfig string, config *server.Config) mux.Middlewar
124124
return func(handler http.Handler) http.Handler {
125125
handler = genericapifilters.WithAuthorization(handler, config.Authorization.Authorizer, scheme.Codecs)
126126
handler = genericapifilters.WithAuthentication(handler, config.Authentication.Authenticator, failedHandler, nil, nil)
127-
handler = genericapifilters.WithRequestInfo(handler, requestInfoResolver)
128127
handler = genericapifilters.WithCacheControl(handler)
129128
return handler
130129
}
131130
}
132131

132+
// RequestInfo returns a middleware function that adds verb/resource/gvk/etc info to the request context.
133+
// This must be set for other filters to function, but only needs to be in each middleware chain once.
134+
func RequestInfo() mux.MiddlewareFunc {
135+
return func(handler http.Handler) http.Handler {
136+
return genericapifilters.WithRequestInfo(handler, requestInfoResolver)
137+
}
138+
}
139+
133140
// MaxInFlight returns a middleware function that limits the number of requests that are executed concurrently.
134141
// This is not strictly auth related, but it also uses the core Kubernetes request filters.
135142
func MaxInFlight(nonMutatingLimit, mutatingLimit int) mux.MiddlewareFunc {
136143
return func(handler http.Handler) http.Handler {
137-
handler = genericfilters.WithMaxInFlightLimit(handler, nonMutatingLimit, mutatingLimit, nil)
138-
handler = genericapifilters.WithRequestInfo(handler, requestInfoResolver)
139-
handler = genericapifilters.WithCacheControl(handler)
140-
return handler
144+
return genericfilters.WithMaxInFlightLimit(handler, nonMutatingLimit, mutatingLimit, nil)
141145
}
142146
}

pkg/server/handlers/router.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func NewHandler(ctx context.Context, control *config.Control, cfg *cmds.Server)
3333
prefix := "/v1-{program}"
3434
authed := mux.NewRouter().SkipClean(true)
3535
authed.NotFoundHandler = APIServer(control, cfg)
36-
authed.Use(auth.HasRole(control, version.Program+":agent", user.NodesGroup, bootstrapapi.BootstrapDefaultGroup), auth.MaxInFlight(maxNonMutatingAgentRequests, maxMutatingAgentRequests))
36+
authed.Use(auth.HasRole(control, version.Program+":agent", user.NodesGroup, bootstrapapi.BootstrapDefaultGroup), auth.RequestInfo(), auth.MaxInFlight(maxNonMutatingAgentRequests, maxMutatingAgentRequests))
3737
authed.Handle(prefix+"/serving-kubelet.crt", ServingKubeletCert(control, nodeAuth))
3838
authed.Handle(prefix+"/client-kubelet.crt", ClientKubeletCert(control, nodeAuth))
3939
authed.Handle(prefix+"/client-kube-proxy.crt", ClientKubeProxyCert(control))

pkg/spegel/bootstrap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func (c *chainingBootstrapper) Get(ctx context.Context) ([]peer.AddrInfo, error)
241241
as, err := b.Get(ctx)
242242
if err != nil {
243243
errs = append(errs, err)
244-
} else {
244+
} else if len(as) != 0 {
245245
return as, nil
246246
}
247247
}

pkg/spegel/spegel.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ func (c *Config) Start(ctx context.Context, nodeConfig *config.Node) error {
256256
func (c *Config) peerInfo() http.HandlerFunc {
257257
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
258258
info, err := c.Bootstrapper.Get(req.Context())
259-
if err != nil || len(info) == 0 {
259+
if err != nil {
260260
http.Error(resp, err.Error(), http.StatusInternalServerError)
261261
return
262262
}
@@ -268,6 +268,11 @@ func (c *Config) peerInfo() http.HandlerFunc {
268268
}
269269
}
270270

271+
if len(addrs) == 0 {
272+
http.Error(resp, "no peer addresses available", http.StatusServiceUnavailable)
273+
return
274+
}
275+
271276
client, _, _ := net.SplitHostPort(req.RemoteAddr)
272277
if req.Header.Get("Accept") == "application/json" {
273278
b, err := json.Marshal(addrs)

0 commit comments

Comments
 (0)