Merge pull request #71500 from yue9944882/chore/homogenize-decoder-error

Transform decoder error into api status error when typer fails
k3s-v1.15.3
Kubernetes Prow Robot 2019-04-25 16:10:27 -07:00 committed by GitHub
commit 6a02542b79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 2 deletions

View File

@ -21,6 +21,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
@ -33,6 +34,7 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/apis/example/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
"//vendor/github.com/evanphx/json-patch:go_default_library",
"//vendor/github.com/google/gofuzz:go_default_library",
"//vendor/k8s.io/utils/trace:go_default_library",

View File

@ -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 {
objGVKs, _, err := typer.ObjectKinds(into)
if err != nil {
return err
return errors.NewBadRequest(err.Error())
}
objGVK := objGVKs[0]
if gvk != nil && len(gvk.Kind) > 0 {

View File

@ -31,6 +31,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"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/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
@ -43,6 +44,7 @@ import (
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
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) {
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
}