mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 06:54:01 +00:00
Merge pull request #68346 from CaoShuFeng/400_500
return 400 status when invalid json patch passed to apiserver
This commit is contained in:
commit
48e93c7329
@ -265,7 +265,7 @@ func (p *jsonPatcher) applyPatchToCurrentObject(currentObject runtime.Object) (r
|
||||
// Apply the patch.
|
||||
patchedObjJS, err := p.applyJSPatch(currentObjJS)
|
||||
if err != nil {
|
||||
return nil, interpretPatchError(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Construct the resulting typed, unversioned object.
|
||||
@ -284,9 +284,13 @@ func (p *jsonPatcher) applyJSPatch(versionedJS []byte) (patchedJS []byte, retErr
|
||||
case types.JSONPatchType:
|
||||
patchObj, err := jsonpatch.DecodePatch(p.patchJS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.NewBadRequest(err.Error())
|
||||
}
|
||||
return patchObj.Apply(versionedJS)
|
||||
patchedJS, err := patchObj.Apply(versionedJS)
|
||||
if err != nil {
|
||||
return nil, errors.NewGenericServerResponse(http.StatusUnprocessableEntity, "", schema.GroupResource{}, "", err.Error(), 0, false)
|
||||
}
|
||||
return patchedJS, nil
|
||||
case types.MergePatchType:
|
||||
return jsonpatch.MergePatch(versionedJS, p.patchJS)
|
||||
default:
|
||||
@ -415,7 +419,7 @@ func applyPatchToObject(
|
||||
) error {
|
||||
patchedObjMap, err := strategicpatch.StrategicMergeMapPatch(originalMap, patchMap, schemaReferenceObj)
|
||||
if err != nil {
|
||||
return interpretPatchError(err)
|
||||
return interpretStrategicMergePatchError(err)
|
||||
}
|
||||
|
||||
// Rather than serialize the patched map to JSON, then decode it to an object, we go directly from a map to an object
|
||||
@ -428,8 +432,8 @@ func applyPatchToObject(
|
||||
return nil
|
||||
}
|
||||
|
||||
// interpretPatchError interprets the error type and returns an error with appropriate HTTP code.
|
||||
func interpretPatchError(err error) error {
|
||||
// interpretStrategicMergePatchError interprets the error type and returns an error with appropriate HTTP code.
|
||||
func interpretStrategicMergePatchError(err error) error {
|
||||
switch err {
|
||||
case mergepatch.ErrBadJSONDoc, mergepatch.ErrBadPatchFormatForPrimitiveList, mergepatch.ErrBadPatchFormatForRetainKeys, mergepatch.ErrBadPatchFormatForSetElementOrderList, mergepatch.ErrUnsupportedStrategicMergePatchFormat:
|
||||
return errors.NewBadRequest(err.Error())
|
||||
|
@ -101,7 +101,7 @@ func TestPatchAnonymousField(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatchInvalid(t *testing.T) {
|
||||
func TestStrategicMergePatchInvalid(t *testing.T) {
|
||||
testGV := schema.GroupVersion{Group: "", Version: "v"}
|
||||
scheme.AddKnownTypes(testGV, &testPatchType{})
|
||||
defaulter := runtime.ObjectDefaulter(scheme)
|
||||
@ -123,6 +123,61 @@ func TestPatchInvalid(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONPatch(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
patch string
|
||||
expectedError string
|
||||
expectedErrorType metav1.StatusReason
|
||||
}{
|
||||
{
|
||||
name: "valid",
|
||||
patch: `[{"op": "test", "value": "podA", "path": "/metadata/name"}]`,
|
||||
},
|
||||
{
|
||||
name: "invalid-syntax",
|
||||
patch: `invalid json patch`,
|
||||
expectedError: "invalid character 'i' looking for beginning of value",
|
||||
expectedErrorType: metav1.StatusReasonBadRequest,
|
||||
},
|
||||
{
|
||||
name: "invalid-semantics",
|
||||
patch: `[{"op": "test", "value": "podA", "path": "/invalid/path"}]`,
|
||||
expectedError: "the server rejected our request due to an error in our request",
|
||||
expectedErrorType: metav1.StatusReasonInvalid,
|
||||
},
|
||||
} {
|
||||
p := &patcher{
|
||||
patchType: types.JSONPatchType,
|
||||
patchJS: []byte(test.patch),
|
||||
}
|
||||
jp := jsonPatcher{p}
|
||||
codec := codecs.LegacyCodec(examplev1.SchemeGroupVersion)
|
||||
pod := &examplev1.Pod{}
|
||||
pod.Name = "podA"
|
||||
versionedJS, err := runtime.Encode(codec, pod)
|
||||
if err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
_, err = jp.applyJSPatch(versionedJS)
|
||||
if err != nil {
|
||||
if len(test.expectedError) == 0 {
|
||||
t.Errorf("%s: expect no error when applying json patch, but got %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
if err.Error() != test.expectedError {
|
||||
t.Errorf("%s: expected error %v, but got %v", test.name, test.expectedError, err)
|
||||
}
|
||||
if test.expectedErrorType != apierrors.ReasonForError(err) {
|
||||
t.Errorf("%s: expected error type %v, but got %v", test.name, test.expectedErrorType, apierrors.ReasonForError(err))
|
||||
}
|
||||
} else if len(test.expectedError) > 0 {
|
||||
t.Errorf("%s: expected err %s", test.name, test.expectedError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatchCustomResource(t *testing.T) {
|
||||
testGV := schema.GroupVersion{Group: "mygroup.example.com", Version: "v1beta1"}
|
||||
scheme.AddKnownTypes(testGV, &unstructured.Unstructured{})
|
||||
|
Loading…
Reference in New Issue
Block a user