mirror of https://github.com/k3s-io/k3s
72 lines
2.1 KiB
Go
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(),
|
||
|
}}
|
||
|
}
|