k3s/pkg/util/apierrors.go
Brad Davidson 7a2a2d075c Move error response generation code into util
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
2024-03-26 15:17:15 -07:00

72 lines
2.1 KiB
Go

package util
import (
"net/http"
"github.com/k3s-io/k3s/pkg/generated/clientset/versioned/scheme"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
)
var ErrNotReady = errors.New("apiserver not ready")
// SendError sends a properly formatted error response
func SendError(err error, resp http.ResponseWriter, req *http.Request, status ...int) {
var code int
if len(status) == 1 {
code = status[0]
}
if code == 0 || code == http.StatusOK {
code = http.StatusInternalServerError
}
// Don't log "apiserver not ready" errors, they are frequent during startup
if !errors.Is(err, ErrNotReady) {
logrus.Errorf("Sending HTTP %d response to %s: %v", code, req.RemoteAddr, err)
}
var serr *apierrors.StatusError
switch code {
case http.StatusBadRequest:
serr = apierrors.NewBadRequest(err.Error())
case http.StatusUnauthorized:
serr = apierrors.NewUnauthorized(err.Error())
case http.StatusForbidden:
serr = newForbidden(err)
case http.StatusInternalServerError:
serr = apierrors.NewInternalError(err)
case http.StatusBadGateway:
serr = newBadGateway(err)
case http.StatusServiceUnavailable:
serr = apierrors.NewServiceUnavailable(err.Error())
default:
serr = apierrors.NewGenericServerResponse(code, req.Method, schema.GroupResource{}, req.URL.Path, err.Error(), 0, true)
}
responsewriters.ErrorNegotiated(serr, scheme.Codecs.WithoutConversion(), schema.GroupVersion{}, resp, req)
}
func newForbidden(err error) *apierrors.StatusError {
return &apierrors.StatusError{
ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusForbidden,
Reason: metav1.StatusReasonForbidden,
Message: err.Error(),
}}
}
func newBadGateway(err error) *apierrors.StatusError {
return &apierrors.StatusError{
ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusBadGateway,
Reason: metav1.StatusReasonInternalError,
Message: err.Error(),
}}
}