Guarantee that status errors have a kind set
Some errors are invoked outside of negotiation. These errors should still have a kind and apiVersion (which is only set by structured encoders, not always availabe). Ensure that all errors by default get a status kind and version set. Kubernetes-commit: a1e44fc69bf0faeb47e6d2ebfc2709bbc3f17221
This commit is contained in:
parent
ac8d2245af
commit
089e209aad
|
@ -1922,6 +1922,15 @@ func TestGetTable(t *testing.T) {
|
||||||
if resp.StatusCode != test.statusCode {
|
if resp.StatusCode != test.statusCode {
|
||||||
t.Errorf("%d: unexpected response: %#v", i, resp)
|
t.Errorf("%d: unexpected response: %#v", i, resp)
|
||||||
}
|
}
|
||||||
|
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%d: unexpected body read error: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
||||||
|
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
||||||
|
t.Errorf("%d: unexpected error body: %#v", obj)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
@ -2038,6 +2047,15 @@ func TestGetPartialObjectMetadata(t *testing.T) {
|
||||||
if resp.StatusCode != test.statusCode {
|
if resp.StatusCode != test.statusCode {
|
||||||
t.Errorf("%d: unexpected response: %#v", i, resp)
|
t.Errorf("%d: unexpected response: %#v", i, resp)
|
||||||
}
|
}
|
||||||
|
obj, _, err := extractBodyObject(resp, unstructured.UnstructuredJSONScheme)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%d: unexpected body read error: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gvk := schema.GroupVersionKind{Version: "v1", Kind: "Status"}
|
||||||
|
if obj.GetObjectKind().GroupVersionKind() != gvk {
|
||||||
|
t.Errorf("%d: unexpected error body: %#v", obj)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
|
|
@ -68,15 +68,15 @@ func TestForbidden(t *testing.T) {
|
||||||
reason string
|
reason string
|
||||||
contentType string
|
contentType string
|
||||||
}{
|
}{
|
||||||
{`{"metadata":{},"status":"Failure","message":"forbidden: User \"NAME\" cannot GET path \"/whatever\"","reason":"Forbidden","details":{},"code":403}
|
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User \"NAME\" cannot GET path \"/whatever\"","reason":"Forbidden","details":{},"code":403}
|
||||||
`, authorizer.AttributesRecord{User: u, Verb: "GET", Path: "/whatever"}, "", "application/json"},
|
`, authorizer.AttributesRecord{User: u, Verb: "GET", Path: "/whatever"}, "", "application/json"},
|
||||||
{`{"metadata":{},"status":"Failure","message":"forbidden: User \"NAME\" cannot GET path \"/\u0026lt;script\u0026gt;\"","reason":"Forbidden","details":{},"code":403}
|
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User \"NAME\" cannot GET path \"/\u0026lt;script\u0026gt;\"","reason":"Forbidden","details":{},"code":403}
|
||||||
`, authorizer.AttributesRecord{User: u, Verb: "GET", Path: "/<script>"}, "", "application/json"},
|
`, authorizer.AttributesRecord{User: u, Verb: "GET", Path: "/<script>"}, "", "application/json"},
|
||||||
{`{"metadata":{},"status":"Failure","message":"pod is forbidden: User \"NAME\" cannot GET pod at the cluster scope","reason":"Forbidden","details":{"kind":"pod"},"code":403}
|
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pod is forbidden: User \"NAME\" cannot GET pod at the cluster scope","reason":"Forbidden","details":{"kind":"pod"},"code":403}
|
||||||
`, authorizer.AttributesRecord{User: u, Verb: "GET", Resource: "pod", ResourceRequest: true}, "", "application/json"},
|
`, authorizer.AttributesRecord{User: u, Verb: "GET", Resource: "pod", ResourceRequest: true}, "", "application/json"},
|
||||||
{`{"metadata":{},"status":"Failure","message":"pod \"mypod\" is forbidden: User \"NAME\" cannot GET pod at the cluster scope","reason":"Forbidden","details":{"name":"mypod","kind":"pod"},"code":403}
|
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pod \"mypod\" is forbidden: User \"NAME\" cannot GET pod at the cluster scope","reason":"Forbidden","details":{"name":"mypod","kind":"pod"},"code":403}
|
||||||
`, authorizer.AttributesRecord{User: u, Verb: "GET", Resource: "pod", ResourceRequest: true, Name: "mypod"}, "", "application/json"},
|
`, authorizer.AttributesRecord{User: u, Verb: "GET", Resource: "pod", ResourceRequest: true, Name: "mypod"}, "", "application/json"},
|
||||||
{`{"metadata":{},"status":"Failure","message":"pod.v2 is forbidden: User \"NAME\" cannot GET pod.v2/quota in the namespace \"test\"","reason":"Forbidden","details":{"group":"v2","kind":"pod"},"code":403}
|
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pod.v2 is forbidden: User \"NAME\" cannot GET pod.v2/quota in the namespace \"test\"","reason":"Forbidden","details":{"group":"v2","kind":"pod"},"code":403}
|
||||||
`, authorizer.AttributesRecord{User: u, Verb: "GET", Namespace: "test", APIGroup: "v2", Resource: "pod", Subresource: "quota", ResourceRequest: true}, "", "application/json"},
|
`, authorizer.AttributesRecord{User: u, Verb: "GET", Namespace: "test", APIGroup: "v2", Resource: "pod", Subresource: "quota", ResourceRequest: true}, "", "application/json"},
|
||||||
}
|
}
|
||||||
for _, test := range cases {
|
for _, test := range cases {
|
||||||
|
|
|
@ -46,6 +46,8 @@ func ErrorToAPIStatus(err error) *metav1.Status {
|
||||||
status.Code = http.StatusInternalServerError
|
status.Code = http.StatusInternalServerError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
status.Kind = "Status"
|
||||||
|
status.APIVersion = "v1"
|
||||||
//TODO: check for invalid responses
|
//TODO: check for invalid responses
|
||||||
return &status
|
return &status
|
||||||
default:
|
default:
|
||||||
|
@ -61,6 +63,10 @@ func ErrorToAPIStatus(err error) *metav1.Status {
|
||||||
// cases.
|
// cases.
|
||||||
runtime.HandleError(fmt.Errorf("apiserver received an error that is not an metav1.Status: %v", err))
|
runtime.HandleError(fmt.Errorf("apiserver received an error that is not an metav1.Status: %v", err))
|
||||||
return &metav1.Status{
|
return &metav1.Status{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "Status",
|
||||||
|
APIVersion: "v1",
|
||||||
|
},
|
||||||
Status: metav1.StatusFailure,
|
Status: metav1.StatusFailure,
|
||||||
Code: int32(status),
|
Code: int32(status),
|
||||||
Reason: metav1.StatusReasonUnknown,
|
Reason: metav1.StatusReasonUnknown,
|
||||||
|
|
|
@ -65,6 +65,8 @@ func TestAPIStatus(t *testing.T) {
|
||||||
}
|
}
|
||||||
for k, v := range cases {
|
for k, v := range cases {
|
||||||
actual := ErrorToAPIStatus(k)
|
actual := ErrorToAPIStatus(k)
|
||||||
|
v.APIVersion = "v1"
|
||||||
|
v.Kind = "Status"
|
||||||
if !reflect.DeepEqual(actual, &v) {
|
if !reflect.DeepEqual(actual, &v) {
|
||||||
t.Errorf("%s: Expected %#v, Got %#v", k, v, actual)
|
t.Errorf("%s: Expected %#v, Got %#v", k, v, actual)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue