properly transform decoder error into status error
Kubernetes-commit: 1e65162d44f83d74e9802caf34848abed3eb403c
This commit is contained in:
parent
48fa00984a
commit
7195bbdf3c
|
@ -229,11 +229,11 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// transformDecodeError adds additional information when a decode fails.
|
// transformDecodeError adds additional information into a bad-request api error when a decode fails.
|
||||||
func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime.Object, gvk *schema.GroupVersionKind, body []byte) error {
|
func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime.Object, gvk *schema.GroupVersionKind, body []byte) error {
|
||||||
objGVKs, _, err := typer.ObjectKinds(into)
|
objGVKs, _, err := typer.ObjectKinds(into)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.NewBadRequest(err.Error())
|
||||||
}
|
}
|
||||||
objGVK := objGVKs[0]
|
objGVK := objGVKs[0]
|
||||||
if gvk != nil && len(gvk.Kind) > 0 {
|
if gvk != nil && len(gvk.Kind) > 0 {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
testapigroupv1 "k8s.io/apimachinery/pkg/apis/testapigroup/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
|
@ -43,6 +44,7 @@ import (
|
||||||
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
|
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||||
utiltrace "k8s.io/utils/trace"
|
utiltrace "k8s.io/utils/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -950,3 +952,51 @@ func (f mutateObjectUpdateFunc) Handles(operation admission.Operation) bool {
|
||||||
func (f mutateObjectUpdateFunc) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
func (f mutateObjectUpdateFunc) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||||
return f(a.GetObject(), a.GetOldObject())
|
return f(a.GetObject(), a.GetOldObject())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTransformDecodeErrorEnsuresBadRequestError(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
typer runtime.ObjectTyper
|
||||||
|
decodedGVK *schema.GroupVersionKind
|
||||||
|
decodeIntoObject runtime.Object
|
||||||
|
baseErr error
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "decoding normal objects fails and returns a bad-request error",
|
||||||
|
typer: clientgoscheme.Scheme,
|
||||||
|
decodedGVK: &schema.GroupVersionKind{
|
||||||
|
Group: testapigroupv1.GroupName,
|
||||||
|
Version: "v1",
|
||||||
|
Kind: "Carp",
|
||||||
|
},
|
||||||
|
decodeIntoObject: &testapigroupv1.Carp{}, // which client-go's scheme doesn't recognize
|
||||||
|
baseErr: fmt.Errorf("plain error"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "decoding objects with unknown GVK fails and returns a bad-request error",
|
||||||
|
typer: alwaysErrorTyper{},
|
||||||
|
decodedGVK: nil,
|
||||||
|
decodeIntoObject: &testapigroupv1.Carp{}, // which client-go's scheme doesn't recognize
|
||||||
|
baseErr: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
err := transformDecodeError(testCase.typer, testCase.baseErr, testCase.decodeIntoObject, testCase.decodedGVK, []byte(``))
|
||||||
|
if apiStatus, ok := err.(apierrors.APIStatus); !ok || apiStatus.Status().Code != http.StatusBadRequest {
|
||||||
|
t.Errorf("expected bad request error but got: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ runtime.ObjectTyper = alwaysErrorTyper{}
|
||||||
|
|
||||||
|
type alwaysErrorTyper struct{}
|
||||||
|
|
||||||
|
func (alwaysErrorTyper) ObjectKinds(runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||||
|
return nil, false, fmt.Errorf("always error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (alwaysErrorTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue