From 3bc4abb9aa4a3be5bfb3c7f5015339bcfa3e9d18 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Tue, 27 Oct 2015 09:29:18 -0400 Subject: [PATCH] Add TypeMeta to discovery response objects --- pkg/api/register.go | 4 ++++ pkg/api/serialization_test.go | 33 +++++++++++++++++++++++++++++++++ pkg/api/testapi/testapi.go | 4 ++++ pkg/api/unversioned/types.go | 10 +++++++++- pkg/apiserver/apiserver.go | 8 ++++---- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/pkg/api/register.go b/pkg/api/register.go index 917b4a2318d..5ffc82dcab3 100644 --- a/pkg/api/register.go +++ b/pkg/api/register.go @@ -71,6 +71,10 @@ func init() { // Register Unversioned types Scheme.AddKnownTypes("", &unversioned.Status{}) + Scheme.AddKnownTypes("", &unversioned.APIVersions{}) + Scheme.AddKnownTypes("", &unversioned.APIGroupList{}) + Scheme.AddKnownTypes("", &unversioned.APIGroup{}) + Scheme.AddKnownTypes("", &unversioned.APIResourceList{}) } func (*Pod) IsAnAPIObject() {} diff --git a/pkg/api/serialization_test.go b/pkg/api/serialization_test.go index 3a631af7425..5b32f8af6a5 100644 --- a/pkg/api/serialization_test.go +++ b/pkg/api/serialization_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/sets" @@ -94,6 +95,7 @@ func roundTripSame(t *testing.T, item runtime.Object, except ...string) { codec, err := testapi.GetCodecForObject(item) if err != nil { t.Errorf("unexpected error: %v", err) + return } version := testapi.Default.Version() @@ -203,6 +205,37 @@ func TestBadJSONRejection(t *testing.T) { }*/ } +func TestUnversionedTypes(t *testing.T) { + testcases := []runtime.Object{ + &unversioned.Status{Status: "Failure", Message: "something went wrong"}, + &unversioned.APIVersions{Versions: []string{"A", "B", "C"}}, + &unversioned.APIGroupList{Groups: []unversioned.APIGroup{{Name: "mygroup"}}}, + &unversioned.APIGroup{Name: "mygroup"}, + &unversioned.APIResourceList{GroupVersion: "mygroup/myversion"}, + } + + for _, obj := range testcases { + // Make sure the unversioned codec can encode + unversionedJSON, err := api.Codec.Encode(obj) + if err != nil { + t.Errorf("%v: unexpected error: %v", obj, err) + continue + } + + // Make sure the versioned codec under test can decode + versionDecodedObject, err := testapi.Default.Codec().Decode(unversionedJSON) + if err != nil { + t.Errorf("%v: unexpected error: %v", obj, err) + continue + } + // Make sure it decodes correctly + if !reflect.DeepEqual(obj, versionDecodedObject) { + t.Errorf("%v: expected %#v, got %#v", obj, obj, versionDecodedObject) + continue + } + } +} + const benchmarkSeed = 100 func BenchmarkEncode(b *testing.B) { diff --git a/pkg/api/testapi/testapi.go b/pkg/api/testapi/testapi.go index e0a73bd0bda..29573f6618f 100644 --- a/pkg/api/testapi/testapi.go +++ b/pkg/api/testapi/testapi.go @@ -225,5 +225,9 @@ func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) { return group.Codec(), nil } } + // Codec used for unversioned types + if api.Scheme.Recognizes("", kind) { + return api.Codec, nil + } return nil, fmt.Errorf("unexpected kind: %v", kind) } diff --git a/pkg/api/unversioned/types.go b/pkg/api/unversioned/types.go index 809c5851882..c90bf296571 100644 --- a/pkg/api/unversioned/types.go +++ b/pkg/api/unversioned/types.go @@ -270,11 +270,16 @@ const ( CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse" ) -func (*Status) IsAnAPIObject() {} +func (*Status) IsAnAPIObject() {} +func (*APIVersions) IsAnAPIObject() {} +func (*APIGroupList) IsAnAPIObject() {} +func (*APIGroup) IsAnAPIObject() {} +func (*APIResourceList) IsAnAPIObject() {} // APIVersions lists the versions that are available, to allow clients to // discover the API at /api, which is the root path of the legacy v1 API. type APIVersions struct { + TypeMeta `json:",inline"` // versions are the api versions that are available. Versions []string `json:"versions"` } @@ -282,6 +287,7 @@ type APIVersions struct { // APIGroupList is a list of APIGroup, to allow clients to discover the API at // /apis. type APIGroupList struct { + TypeMeta `json:",inline"` // groups is a list of APIGroup. Groups []APIGroup `json:"groups"` } @@ -289,6 +295,7 @@ type APIGroupList struct { // APIGroup contains the name, the supported versions, and the preferred version // of a group. type APIGroup struct { + TypeMeta `json:",inline"` // name is the name of the group. Name string `json:"name"` // versions are the versions supported in this group. @@ -320,6 +327,7 @@ type APIResource struct { // resources supported in a specific group and version, and if the resource // is namespaced. type APIResourceList struct { + TypeMeta `json:",inline"` // groupVersion is the group and version this APIResourceList is for. GroupVersion string `json:"groupVersion"` // resources contains the name of the resources and if they are namespaced. diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 1c0ccdc2cb0..4ccc5738787 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -306,7 +306,7 @@ func handleVersion(req *restful.Request, resp *restful.Response) { func APIVersionHandler(versions ...string) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { // TODO: use restful's Response methods - writeRawJSON(http.StatusOK, unversioned.APIVersions{Versions: versions}, resp.ResponseWriter) + writeJSON(http.StatusOK, api.Codec, &unversioned.APIVersions{Versions: versions}, resp.ResponseWriter, true) } } @@ -314,7 +314,7 @@ func APIVersionHandler(versions ...string) restful.RouteFunction { func RootAPIHandler(groups []unversioned.APIGroup) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { // TODO: use restful's Response methods - writeRawJSON(http.StatusOK, unversioned.APIGroupList{Groups: groups}, resp.ResponseWriter) + writeJSON(http.StatusOK, api.Codec, &unversioned.APIGroupList{Groups: groups}, resp.ResponseWriter, true) } } @@ -323,7 +323,7 @@ func RootAPIHandler(groups []unversioned.APIGroup) restful.RouteFunction { func GroupHandler(group unversioned.APIGroup) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { // TODO: use restful's Response methods - writeRawJSON(http.StatusOK, group, resp.ResponseWriter) + writeJSON(http.StatusOK, api.Codec, &group, resp.ResponseWriter, true) } } @@ -331,7 +331,7 @@ func GroupHandler(group unversioned.APIGroup) restful.RouteFunction { func SupportedResourcesHandler(groupVersion string, apiResources []unversioned.APIResource) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { // TODO: use restful's Response methods - writeRawJSON(http.StatusOK, unversioned.APIResourceList{GroupVersion: groupVersion, APIResources: apiResources}, resp.ResponseWriter) + writeJSON(http.StatusOK, api.Codec, &unversioned.APIResourceList{GroupVersion: groupVersion, APIResources: apiResources}, resp.ResponseWriter, true) } }