Skip to content

Commit

Permalink
Convert remaining http handlers over to use util.SendError
Browse files Browse the repository at this point in the history
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
  • Loading branch information
brandond committed Apr 26, 2024
1 parent 081ebd0 commit 2f6ce7f
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 58 deletions.
12 changes: 7 additions & 5 deletions pkg/cluster/router.go
@@ -1,7 +1,10 @@
package cluster

import (
"fmt"
"net/http"

"github.com/k3s-io/k3s/pkg/util"
)

// getHandler returns a basic request handler that processes requests through
Expand All @@ -19,11 +22,10 @@ func (c *Cluster) getHandler(handler http.Handler) (http.Handler, error) {
// if no additional handlers are available.
func (c *Cluster) router() http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if c.config.Runtime.Handler == nil {
http.Error(rw, "starting", http.StatusServiceUnavailable)
return
if c.config.Runtime.Handler != nil {
c.config.Runtime.Handler.ServeHTTP(rw, req)
} else {
util.SendError(fmt.Errorf("starting"), rw, req, http.StatusServiceUnavailable)
}

c.config.Runtime.Handler.ServeHTTP(rw, req)
})
}
3 changes: 1 addition & 2 deletions pkg/daemons/control/tunnel.go
Expand Up @@ -29,8 +29,7 @@ var defaultDialer = net.Dialer{}

func loggingErrorWriter(rw http.ResponseWriter, req *http.Request, code int, err error) {
logrus.Debugf("Tunnel server error: %d %v", code, err)
rw.WriteHeader(code)
rw.Write([]byte(err.Error()))
util.SendError(err, rw, req, code)
}

func setupTunnel(ctx context.Context, cfg *config.Control) (http.Handler, error) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/etcd/etcd.go
Expand Up @@ -754,7 +754,7 @@ func getEndpoints(control *config.Control) []string {
// for use by etcd.
func toTLSConfig(runtime *config.ControlRuntime) (*tls.Config, error) {
if runtime.ClientETCDCert == "" || runtime.ClientETCDKey == "" || runtime.ETCDServerCA == "" {
return nil, errors.New("runtime is not ready yet")
return nil, util.ErrCoreNotReady
}

clientCert, err := tls.LoadX509KeyPair(runtime.ClientETCDCert, runtime.ClientETCDKey)
Expand Down Expand Up @@ -1170,7 +1170,7 @@ func (e *ETCD) manageLearners(ctx context.Context) {

func (e *ETCD) getETCDNodes() ([]*v1.Node, error) {
if e.config.Runtime.Core == nil {
return nil, errors.New("runtime core not ready")
return nil, util.ErrCoreNotReady
}

nodes := e.config.Runtime.Core.Core().V1().Node()
Expand Down
4 changes: 2 additions & 2 deletions pkg/server/cert.go
Expand Up @@ -30,8 +30,8 @@ import (

func caCertReplaceHandler(server *config.Control) http.HandlerFunc {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil || req.Method != http.MethodPut {
resp.WriteHeader(http.StatusNotFound)
if req.Method != http.MethodPut {
util.SendError(fmt.Errorf("method not allowed"), resp, req, http.StatusMethodNotAllowed)
return
}
force, _ := strconv.ParseBool(req.FormValue("force"))
Expand Down
41 changes: 10 additions & 31 deletions pkg/server/router.go
Expand Up @@ -200,11 +200,6 @@ func getCACertAndKeys(caCertFile, caKeyFile, signingKeyFile string) ([]*x509.Cer

func servingKubeletCert(server *config.Control, keyFile string, auth nodePassBootstrapper) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil {
resp.WriteHeader(http.StatusNotFound)
return
}

nodeName, errCode, err := auth(req)
if err != nil {
util.SendError(err, resp, req, errCode)
Expand Down Expand Up @@ -256,11 +251,6 @@ func servingKubeletCert(server *config.Control, keyFile string, auth nodePassBoo

func clientKubeletCert(server *config.Control, keyFile string, auth nodePassBootstrapper) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil {
resp.WriteHeader(http.StatusNotFound)
return
}

nodeName, errCode, err := auth(req)
if err != nil {
util.SendError(err, resp, req, errCode)
Expand Down Expand Up @@ -296,10 +286,6 @@ func clientKubeletCert(server *config.Control, keyFile string, auth nodePassBoot

func fileHandler(fileName ...string) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil {
resp.WriteHeader(http.StatusNotFound)
return
}
resp.Header().Set("Content-Type", "text/plain")

if len(fileName) == 1 {
Expand All @@ -310,8 +296,7 @@ func fileHandler(fileName ...string) http.Handler {
for _, f := range fileName {
bytes, err := os.ReadFile(f)
if err != nil {
logrus.Errorf("Failed to read %s: %v", f, err)
resp.WriteHeader(http.StatusInternalServerError)
util.SendError(errors.Wrapf(err, "failed to read %s", f), resp, req, http.StatusInternalServerError)
return
}
resp.Write(bytes)
Expand All @@ -336,49 +321,43 @@ func apiserversHandler(server *config.Control) http.Handler {

resp.Header().Set("content-type", "application/json")
if err := json.NewEncoder(resp).Encode(endpoints); err != nil {
logrus.Errorf("Failed to encode apiserver endpoints: %v", err)
resp.WriteHeader(http.StatusInternalServerError)
util.SendError(errors.Wrap(err, "failed to encode apiserver endpoints"), resp, req, http.StatusInternalServerError)
}
})
}

func configHandler(server *config.Control, cfg *cmds.Server) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil {
resp.WriteHeader(http.StatusNotFound)
return
}
// Startup hooks may read and modify cmds.Server in a goroutine, but as these are copied into
// config.Control before the startup hooks are called, any modifications need to be sync'd back
// into the struct before it is sent to agents.
// At this time we don't sync all the fields, just those known to be touched by startup hooks.
server.DisableKubeProxy = cfg.DisableKubeProxy
resp.Header().Set("content-type", "application/json")
if err := json.NewEncoder(resp).Encode(server); err != nil {
logrus.Errorf("Failed to encode agent config: %v", err)
resp.WriteHeader(http.StatusInternalServerError)
util.SendError(errors.Wrap(err, "failed to encode agent config"), resp, req, http.StatusInternalServerError)
}
})
}

func readyzHandler(server *config.Control) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
code := http.StatusOK
data := []byte("ok")
if server.Runtime.Core == nil {
code = http.StatusInternalServerError
data = []byte("runtime core not ready")
util.SendError(util.ErrCoreNotReady, resp, req, http.StatusServiceUnavailable)
return
}
resp.WriteHeader(code)
data := []byte("ok")
resp.WriteHeader(http.StatusOK)
resp.Header().Set("Content-Type", "text/plain")
resp.Header().Set("Content-length", strconv.Itoa(len(data)))
resp.Header().Set("Content-Length", strconv.Itoa(len(data)))
resp.Write(data)
})
}

func ping() http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
data := []byte("pong")
resp.WriteHeader(http.StatusOK)
resp.Header().Set("Content-Type", "text/plain")
resp.Header().Set("Content-Length", strconv.Itoa(len(data)))
resp.Write(data)
Expand Down Expand Up @@ -432,7 +411,7 @@ func passwordBootstrap(ctx context.Context, config *Config) nodePassBootstrapper
return verifyRemotePassword(ctx, config, &mu, deferredNodes, node)
} else {
// Otherwise, reject the request until the core is ready.
return "", http.StatusServiceUnavailable, errors.New("runtime core not ready")
return "", http.StatusServiceUnavailable, util.ErrCoreNotReady
}
}

Expand Down
13 changes: 2 additions & 11 deletions pkg/server/secrets-encrypt.go
Expand Up @@ -56,10 +56,6 @@ func getEncryptionRequest(req *http.Request) (*EncryptionRequest, error) {

func encryptionStatusHandler(server *config.Control) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil {
resp.WriteHeader(http.StatusNotFound)
return
}
status, err := encryptionStatus(server)
if err != nil {
util.SendErrorWithID(err, "secret-encrypt", resp, req, http.StatusInternalServerError)
Expand Down Expand Up @@ -160,18 +156,13 @@ func encryptionEnable(ctx context.Context, server *config.Control, enable bool)

func encryptionConfigHandler(ctx context.Context, server *config.Control) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil {
resp.WriteHeader(http.StatusNotFound)
return
}
if req.Method != http.MethodPut {
resp.WriteHeader(http.StatusBadRequest)
util.SendError(fmt.Errorf("method not allowed"), resp, req, http.StatusMethodNotAllowed)
return
}
encryptReq, err := getEncryptionRequest(req)
if err != nil {
resp.WriteHeader(http.StatusBadRequest)
resp.Write([]byte(err.Error()))
util.SendError(err, resp, req, http.StatusBadRequest)
return
}
if encryptReq.Stage != nil {
Expand Down
7 changes: 3 additions & 4 deletions pkg/server/token.go
Expand Up @@ -32,16 +32,15 @@ func getServerTokenRequest(req *http.Request) (TokenRotateRequest, error) {

func tokenRequestHandler(ctx context.Context, server *config.Control) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
if req.TLS == nil || req.Method != http.MethodPut {
resp.WriteHeader(http.StatusBadRequest)
if req.Method != http.MethodPut {
util.SendError(fmt.Errorf("method not allowed"), resp, req, http.StatusMethodNotAllowed)
return
}
var err error
sTokenReq, err := getServerTokenRequest(req)
logrus.Debug("Received token request")
if err != nil {
resp.WriteHeader(http.StatusBadRequest)
resp.Write([]byte(err.Error()))
util.SendError(err, resp, req, http.StatusBadRequest)
return
}
if err = tokenRotate(ctx, server, *sTokenReq.NewToken); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion pkg/spegel/bootstrap.go
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/k3s-io/k3s/pkg/clientaccess"
"github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/util"
"github.com/k3s-io/k3s/pkg/version"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/pkg/errors"
Expand Down Expand Up @@ -133,7 +134,7 @@ func (s *serverBootstrapper) Run(_ context.Context, id string) error {

func (s *serverBootstrapper) Get() (addrInfo *peer.AddrInfo, err error) {
if s.controlConfig.Runtime.Core == nil {
return nil, errors.New("runtime core not ready")
return nil, util.ErrCoreNotReady
}
nodeName := os.Getenv("NODE_NAME")
if nodeName == "" {
Expand Down
1 change: 1 addition & 0 deletions pkg/util/apierrors.go
Expand Up @@ -17,6 +17,7 @@ import (

var ErrAPINotReady = errors.New("apiserver not ready")
var ErrAPIDisabled = errors.New("apiserver disabled")
var ErrCoreNotReady = errors.New("runtime core not ready")

// SendErrorWithID sends and logs a random error ID so that logs can be correlated
// between the REST API (which does not provide any detailed error output, to avoid
Expand Down

0 comments on commit 2f6ce7f

Please sign in to comment.