Skip to content

Commit b21b302

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 5408b0f commit b21b302

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
@@ -121,19 +121,23 @@ func Delegated(clientCA, kubeConfig string, config *server.Config) mux.Middlewar
121121
return func(handler http.Handler) http.Handler {
122122
handler = genericapifilters.WithAuthorization(handler, config.Authorization.Authorizer, scheme.Codecs)
123123
handler = genericapifilters.WithAuthentication(handler, config.Authentication.Authenticator, failedHandler, nil, nil)
124-
handler = genericapifilters.WithRequestInfo(handler, requestInfoResolver)
125124
handler = genericapifilters.WithCacheControl(handler)
126125
return handler
127126
}
128127
}
129128

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

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)