diff --git a/pkg/endpoints/apiserver_test.go b/pkg/endpoints/apiserver_test.go index 553948c08..3d0f1106e 100644 --- a/pkg/endpoints/apiserver_test.go +++ b/pkg/endpoints/apiserver_test.go @@ -1749,14 +1749,14 @@ func TestGetPretty(t *testing.T) { pretty bool }{ {accept: runtime.ContentTypeJSON}, - {accept: runtime.ContentTypeJSON + ";pretty=0"}, + {accept: "application/json;pretty=0"}, {accept: runtime.ContentTypeJSON, userAgent: "kubectl"}, {accept: runtime.ContentTypeJSON, params: url.Values{"pretty": {"0"}}}, {pretty: true, accept: runtime.ContentTypeJSON, userAgent: "curl"}, {pretty: true, accept: runtime.ContentTypeJSON, userAgent: "Mozilla/5.0"}, {pretty: true, accept: runtime.ContentTypeJSON, userAgent: "Wget"}, - {pretty: true, accept: runtime.ContentTypeJSON + ";pretty=1"}, + {pretty: true, accept: "application/json;pretty=1"}, {pretty: true, accept: runtime.ContentTypeJSON, params: url.Values{"pretty": {"1"}}}, {pretty: true, accept: runtime.ContentTypeJSON, params: url.Values{"pretty": {"true"}}}, } @@ -1818,14 +1818,28 @@ func TestGetTable(t *testing.T) { if err != nil { t.Fatal(err) } - partial := meta.AsPartialObjectMetadata(m) - partial.GetObjectKind().SetGroupVersionKind(metav1beta1.SchemeGroupVersion.WithKind("PartialObjectMetadata")) - encodedBody, err := runtime.Encode(metainternalversion.Codecs.LegacyCodec(metav1beta1.SchemeGroupVersion), partial) - if err != nil { - t.Fatal(err) + var encodedV1Beta1Body []byte + { + partial := meta.AsPartialObjectMetadata(m) + partial.GetObjectKind().SetGroupVersionKind(metav1beta1.SchemeGroupVersion.WithKind("PartialObjectMetadata")) + encodedBody, err := runtime.Encode(metainternalversion.Codecs.LegacyCodec(metav1beta1.SchemeGroupVersion), partial) + if err != nil { + t.Fatal(err) + } + // the codec includes a trailing newline that is not present during decode + encodedV1Beta1Body = bytes.TrimSpace(encodedBody) + } + var encodedV1Body []byte + { + partial := meta.AsPartialObjectMetadata(m) + partial.GetObjectKind().SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("PartialObjectMetadata")) + encodedBody, err := runtime.Encode(metainternalversion.Codecs.LegacyCodec(metav1.SchemeGroupVersion), partial) + if err != nil { + t.Fatal(err) + } + // the codec includes a trailing newline that is not present during decode + encodedV1Body = bytes.TrimSpace(encodedBody) } - // the codec includes a trailing newline that is not present during decode - encodedBody = bytes.TrimSpace(encodedBody) metaDoc := metav1.ObjectMeta{}.SwaggerDoc() @@ -1838,16 +1852,36 @@ func TestGetTable(t *testing.T) { item bool }{ { - accept: runtime.ContentTypeJSON + ";as=Table;v=v1;g=meta.k8s.io", + accept: "application/json;as=Table;v=v1alpha1;g=meta.k8s.io", statusCode: http.StatusNotAcceptable, }, { accept: runtime.ContentTypeProtobuf + ";as=Table;v=v1beta1;g=meta.k8s.io", statusCode: http.StatusNotAcceptable, }, + { + accept: runtime.ContentTypeProtobuf + ";as=Table;v=v1;g=meta.k8s.io", + statusCode: http.StatusNotAcceptable, + }, + { item: true, - accept: runtime.ContentTypeJSON + ";as=Table;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=Table;v=v1;g=meta.k8s.io", + expected: &metav1.Table{ + TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"}, + ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, + ColumnDefinitions: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, + {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, + }, + Rows: []metav1.TableRow{ + {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Body}}, + }, + }, + }, + { + item: true, + accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io", expected: &metav1beta1.Table{ TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, @@ -1856,7 +1890,7 @@ func TestGetTable(t *testing.T) { {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, }, Rows: []metav1beta1.TableRow{ - {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}}, + {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}}, }, }, }, @@ -1864,7 +1898,7 @@ func TestGetTable(t *testing.T) { item: true, accept: strings.Join([]string{ runtime.ContentTypeProtobuf + ";as=Table;v=v1beta1;g=meta.k8s.io", - runtime.ContentTypeJSON + ";as=Table;v=v1beta1;g=meta.k8s.io", + "application/json;as=Table;v=v1beta1;g=meta.k8s.io", }, ","), expected: &metav1beta1.Table{ TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, @@ -1874,13 +1908,13 @@ func TestGetTable(t *testing.T) { {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, }, Rows: []metav1beta1.TableRow{ - {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}}, + {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}}, }, }, }, { item: true, - accept: runtime.ContentTypeJSON + ";as=Table;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io", params: url.Values{"includeObject": []string{"Metadata"}}, expected: &metav1beta1.Table{ TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, @@ -1890,12 +1924,12 @@ func TestGetTable(t *testing.T) { {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, }, Rows: []metav1beta1.TableRow{ - {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}}, + {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}}, }, }, }, { - accept: runtime.ContentTypeJSON + ";as=Table;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io", params: url.Values{"includeObject": []string{"Metadata"}}, expected: &metav1beta1.Table{ TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, @@ -1905,7 +1939,7 @@ func TestGetTable(t *testing.T) { {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, }, Rows: []metav1beta1.TableRow{ - {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}}, + {Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}}, }, }, }, @@ -1996,6 +2030,13 @@ func TestWatchTable(t *testing.T) { // the codec includes a trailing newline that is not present during decode encodedBody = bytes.TrimSpace(encodedBody) + encodedBodyV1, err := runtime.Encode(metainternalversion.Codecs.LegacyCodec(metav1.SchemeGroupVersion), partial) + if err != nil { + t.Fatal(err) + } + // the codec includes a trailing newline that is not present during decode + encodedBodyV1 = bytes.TrimSpace(encodedBodyV1) + metaDoc := metav1.ObjectMeta{}.SwaggerDoc() s := metainternalversion.Codecs.SupportedMediaTypes()[0].Serializer @@ -2011,11 +2052,11 @@ func TestWatchTable(t *testing.T) { item bool }{ { - accept: runtime.ContentTypeJSON + ";as=Table;v=v1;g=meta.k8s.io", + accept: "application/json;as=Table;v=v1alpha1;g=meta.k8s.io", statusCode: http.StatusNotAcceptable, }, { - accept: runtime.ContentTypeJSON + ";as=Table;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io", send: func(w *watch.FakeWatcher) { w.Add(&obj) }, @@ -2039,7 +2080,7 @@ func TestWatchTable(t *testing.T) { }, }, { - accept: runtime.ContentTypeJSON + ";as=Table;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io", send: func(w *watch.FakeWatcher) { w.Add(&obj) w.Modify(&obj) @@ -2075,6 +2116,43 @@ func TestWatchTable(t *testing.T) { }, }, }, + { + accept: "application/json;as=Table;v=v1;g=meta.k8s.io", + send: func(w *watch.FakeWatcher) { + w.Add(&obj) + w.Modify(&obj) + }, + expected: []*metav1.WatchEvent{ + { + Type: "ADDED", + Object: runtime.RawExtension{ + Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{ + TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"}, + ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, + ColumnDefinitions: []metav1beta1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, + {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, + }, + Rows: []metav1.TableRow{ + {Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBodyV1}}, + }, + }))), + }, + }, + { + Type: "MODIFIED", + Object: runtime.RawExtension{ + Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{ + TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"}, + ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, + Rows: []metav1.TableRow{ + {Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBodyV1}}, + }, + }))), + }, + }, + }, + }, } for i, test := range tests { t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { @@ -2122,6 +2200,7 @@ func TestWatchTable(t *testing.T) { if err != nil { t.Fatal(err) } + defer resp.Body.Close() if test.statusCode != 0 { if resp.StatusCode != test.statusCode { t.Fatalf("%d: unexpected response: %#v", i, resp) @@ -2228,46 +2307,72 @@ func TestGetPartialObjectMetadata(t *testing.T) { statusCode int }{ { - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadata;v=v1;g=meta.k8s.io", + accept: "application/json;as=PartialObjectMetadata;v=v1alpha1;g=meta.k8s.io", statusCode: http.StatusNotAcceptable, }, { - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadata;v=v1;g=meta.k8s.io, application/json", + accept: "application/json;as=PartialObjectMetadata;v=v1alpha1;g=meta.k8s.io, application/json", expectKind: schema.GroupVersionKind{Kind: "Simple", Group: testGroupVersion.Group, Version: testGroupVersion.Version}, }, { - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io, application/json", + accept: "application/json;as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io, application/json", expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadata", Group: "meta.k8s.io", Version: "v1beta1"}, }, { list: true, - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io", statusCode: http.StatusNotAcceptable, }, + + // verify preferred version overrides supported version + { + accept: "application/json;as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io, application/json;as=PartialObjectMetadata;v=v1;g=meta.k8s.io, application/json", + expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadata", Group: "meta.k8s.io", Version: "v1beta1"}, + }, + { + accept: "application/json;as=PartialObjectMetadata;v=v1;g=meta.k8s.io, application/json;as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io, application/json", + expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadata", Group: "meta.k8s.io", Version: "v1"}, + }, + { + accept: "application/json;as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io, application/json;as=PartialObjectMetadata;v=v1;g=meta.k8s.io", + expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadata", Group: "meta.k8s.io", Version: "v1beta1"}, + }, + { + accept: "application/json;as=PartialObjectMetadata;v=v1;g=meta.k8s.io, application/json;as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io", + expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadata", Group: "meta.k8s.io", Version: "v1"}, + }, + { list: true, - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadata;v=v1;g=meta.k8s.io, application/json", + accept: "application/json;as=PartialObjectMetadata;v=v1alpha1;g=meta.k8s.io, application/json", expectKind: schema.GroupVersionKind{Kind: "SimpleList", Group: testGroupVersion.Group, Version: testGroupVersion.Version}, }, { list: true, - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadataList;v=v1beta1;g=meta.k8s.io, application/json", + accept: "application/json;as=PartialObjectMetadataList;v=v1beta1;g=meta.k8s.io, application/json", expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadataList", Group: "meta.k8s.io", Version: "v1beta1"}, }, { - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadataList;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=PartialObjectMetadataList;v=v1beta1;g=meta.k8s.io", statusCode: http.StatusNotAcceptable, }, { - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=PartialObjectMetadata;v=v1beta1;g=meta.k8s.io", expected: &metav1beta1.PartialObjectMetadata{ ObjectMeta: metav1.ObjectMeta{Name: "foo1", Namespace: "ns1", CreationTimestamp: now, UID: types.UID("abcdef0123")}, }, expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadata", Group: "meta.k8s.io", Version: "v1beta1"}, }, + { + accept: "application/json;as=PartialObjectMetadata;v=v1;g=meta.k8s.io", + expected: &metav1.PartialObjectMetadata{ + ObjectMeta: metav1.ObjectMeta{Name: "foo1", Namespace: "ns1", CreationTimestamp: now, UID: types.UID("abcdef0123")}, + }, + expectKind: schema.GroupVersionKind{Kind: "PartialObjectMetadata", Group: "meta.k8s.io", Version: "v1"}, + }, { list: true, - accept: runtime.ContentTypeJSON + ";as=PartialObjectMetadataList;v=v1beta1;g=meta.k8s.io", + accept: "application/json;as=PartialObjectMetadataList;v=v1beta1;g=meta.k8s.io", expected: &metav1beta1.PartialObjectMetadataList{ ListMeta: metav1.ListMeta{ ResourceVersion: "10", diff --git a/pkg/endpoints/handlers/response.go b/pkg/endpoints/handlers/response.go index 214dbc1e7..0fe8a71c7 100644 --- a/pkg/endpoints/handlers/response.go +++ b/pkg/endpoints/handlers/response.go @@ -49,18 +49,18 @@ func transformObject(ctx context.Context, obj runtime.Object, opts interface{}, case target == nil: return obj, nil - case target.Kind == "PartialObjectMetadata" && target.GroupVersion() == metav1beta1.SchemeGroupVersion: - return asV1Beta1PartialObjectMetadata(obj) + case target.Kind == "PartialObjectMetadata": + return asPartialObjectMetadata(obj, target.GroupVersion()) - case target.Kind == "PartialObjectMetadataList" && target.GroupVersion() == metav1beta1.SchemeGroupVersion: - return asV1Beta1PartialObjectMetadataList(obj) + case target.Kind == "PartialObjectMetadataList": + return asPartialObjectMetadataList(obj, target.GroupVersion()) - case target.Kind == "Table" && target.GroupVersion() == metav1beta1.SchemeGroupVersion: + case target.Kind == "Table": options, ok := opts.(*metav1beta1.TableOptions) if !ok { return nil, fmt.Errorf("unexpected TableOptions, got %T", opts) } - return asV1Beta1Table(ctx, obj, options, scope) + return asTable(ctx, obj, options, scope, target.GroupVersion()) default: accepted, _ := negotiation.MediaTypesForSerializer(metainternalversion.Codecs) @@ -74,7 +74,7 @@ func transformObject(ctx context.Context, obj runtime.Object, opts interface{}, func optionsForTransform(mediaType negotiation.MediaTypeOptions, req *http.Request) (interface{}, error) { switch target := mediaType.Convert; { case target == nil: - case target.Kind == "Table" && target.GroupVersion() == metav1beta1.SchemeGroupVersion: + case target.Kind == "Table" && (target.GroupVersion() == metav1beta1.SchemeGroupVersion || target.GroupVersion() == metav1.SchemeGroupVersion): opts := &metav1beta1.TableOptions{} if err := metav1beta1.ParameterCodec.DecodeParameters(req.URL.Query(), metav1beta1.SchemeGroupVersion, opts); err != nil { return nil, err @@ -95,9 +95,8 @@ func optionsForTransform(mediaType negotiation.MediaTypeOptions, req *http.Reque func targetEncodingForTransform(scope *RequestScope, mediaType negotiation.MediaTypeOptions, req *http.Request) (schema.GroupVersionKind, runtime.NegotiatedSerializer, bool) { switch target := mediaType.Convert; { case target == nil: - case target.Kind == "PartialObjectMetadata" && target.GroupVersion() == metav1beta1.SchemeGroupVersion, - target.Kind == "PartialObjectMetadataList" && target.GroupVersion() == metav1beta1.SchemeGroupVersion, - target.Kind == "Table" && target.GroupVersion() == metav1beta1.SchemeGroupVersion: + case (target.Kind == "PartialObjectMetadata" || target.Kind == "PartialObjectMetadataList" || target.Kind == "Table") && + (target.GroupVersion() == metav1beta1.SchemeGroupVersion || target.GroupVersion() == metav1.SchemeGroupVersion): return *target, metainternalversion.Codecs, true } return scope.Kind, scope.Serializer, false @@ -142,31 +141,39 @@ func (e errNotAcceptable) Status() metav1.Status { } } -func asV1Beta1Table(ctx context.Context, result runtime.Object, opts *metav1beta1.TableOptions, scope *RequestScope) (runtime.Object, error) { - table, err := scope.TableConvertor.ConvertToTable(ctx, result, opts) +func asTable(ctx context.Context, result runtime.Object, opts *metav1beta1.TableOptions, scope *RequestScope, groupVersion schema.GroupVersion) (runtime.Object, error) { + switch groupVersion { + case metav1beta1.SchemeGroupVersion, metav1.SchemeGroupVersion: + default: + return nil, newNotAcceptableError(fmt.Sprintf("no Table exists in group version %s", groupVersion)) + } + + obj, err := scope.TableConvertor.ConvertToTable(ctx, result, opts) if err != nil { return nil, err } + table := (*metav1.Table)(obj) + for i := range table.Rows { item := &table.Rows[i] switch opts.IncludeObject { - case metav1beta1.IncludeObject: + case metav1.IncludeObject: item.Object.Object, err = scope.Convertor.ConvertToVersion(item.Object.Object, scope.Kind.GroupVersion()) if err != nil { return nil, err } // TODO: rely on defaulting for the value here? - case metav1beta1.IncludeMetadata, "": + case metav1.IncludeMetadata, "": m, err := meta.Accessor(item.Object.Object) if err != nil { return nil, err } // TODO: turn this into an internal type and do conversion in order to get object kind automatically set? partial := meta.AsPartialObjectMetadata(m) - partial.GetObjectKind().SetGroupVersionKind(metav1beta1.SchemeGroupVersion.WithKind("PartialObjectMetadata")) + partial.GetObjectKind().SetGroupVersionKind(groupVersion.WithKind("PartialObjectMetadata")) item.Object.Object = partial - case metav1beta1.IncludeNone: + case metav1.IncludeNone: item.Object.Object = nil default: err = errors.NewBadRequest(fmt.Sprintf("unrecognized includeObject value: %q", opts.IncludeObject)) @@ -177,42 +184,74 @@ func asV1Beta1Table(ctx context.Context, result runtime.Object, opts *metav1beta return table, nil } -func asV1Beta1PartialObjectMetadata(result runtime.Object) (runtime.Object, error) { +func asPartialObjectMetadata(result runtime.Object, groupVersion schema.GroupVersion) (runtime.Object, error) { if meta.IsListType(result) { err := newNotAcceptableError(fmt.Sprintf("you requested PartialObjectMetadata, but the requested object is a list (%T)", result)) return nil, err } + switch groupVersion { + case metav1beta1.SchemeGroupVersion, metav1.SchemeGroupVersion: + default: + return nil, newNotAcceptableError(fmt.Sprintf("no PartialObjectMetadataList exists in group version %s", groupVersion)) + } m, err := meta.Accessor(result) if err != nil { return nil, err } partial := meta.AsPartialObjectMetadata(m) - partial.GetObjectKind().SetGroupVersionKind(metav1beta1.SchemeGroupVersion.WithKind("PartialObjectMetadata")) + partial.GetObjectKind().SetGroupVersionKind(groupVersion.WithKind("PartialObjectMetadata")) return partial, nil } -func asV1Beta1PartialObjectMetadataList(result runtime.Object) (runtime.Object, error) { - if !meta.IsListType(result) { +func asPartialObjectMetadataList(result runtime.Object, groupVersion schema.GroupVersion) (runtime.Object, error) { + li, ok := result.(metav1.ListInterface) + if !ok { return nil, newNotAcceptableError(fmt.Sprintf("you requested PartialObjectMetadataList, but the requested object is not a list (%T)", result)) } - list := &metav1beta1.PartialObjectMetadataList{} - if li, ok := result.(metav1.ListInterface); ok { + + gvk := groupVersion.WithKind("PartialObjectMetadata") + switch { + case groupVersion == metav1beta1.SchemeGroupVersion: + list := &metav1beta1.PartialObjectMetadataList{} + err := meta.EachListItem(result, func(obj runtime.Object) error { + m, err := meta.Accessor(obj) + if err != nil { + return err + } + partial := meta.AsPartialObjectMetadata(m) + partial.GetObjectKind().SetGroupVersionKind(gvk) + list.Items = append(list.Items, partial) + return nil + }) + if err != nil { + return nil, err + } list.SelfLink = li.GetSelfLink() list.ResourceVersion = li.GetResourceVersion() list.Continue = li.GetContinue() - } - err := meta.EachListItem(result, func(obj runtime.Object) error { - m, err := meta.Accessor(obj) + return list, nil + + case groupVersion == metav1.SchemeGroupVersion: + list := &metav1.PartialObjectMetadataList{} + err := meta.EachListItem(result, func(obj runtime.Object) error { + m, err := meta.Accessor(obj) + if err != nil { + return err + } + partial := meta.AsPartialObjectMetadata(m) + partial.GetObjectKind().SetGroupVersionKind(gvk) + list.Items = append(list.Items, partial) + return nil + }) if err != nil { - return err + return nil, err } - partial := meta.AsPartialObjectMetadata(m) - partial.GetObjectKind().SetGroupVersionKind(metav1beta1.SchemeGroupVersion.WithKind("PartialObjectMetadata")) - list.Items = append(list.Items, partial) - return nil - }) - if err != nil { - return nil, err + list.SelfLink = li.GetSelfLink() + list.ResourceVersion = li.GetResourceVersion() + list.Continue = li.GetContinue() + return list, nil + + default: + return nil, newNotAcceptableError(fmt.Sprintf("no PartialObjectMetadataList exists in group version %s", groupVersion)) } - return list, nil } diff --git a/pkg/endpoints/handlers/rest.go b/pkg/endpoints/handlers/rest.go index 6adbf8495..4db0c0676 100644 --- a/pkg/endpoints/handlers/rest.go +++ b/pkg/endpoints/handlers/rest.go @@ -78,7 +78,7 @@ func (scope *RequestScope) err(err error, w http.ResponseWriter, req *http.Reque func (scope *RequestScope) AllowsConversion(gvk schema.GroupVersionKind, mimeType, mimeSubType string) bool { // TODO: this is temporary, replace with an abstraction calculated at endpoint installation time - if gvk.GroupVersion() == metav1beta1.SchemeGroupVersion { + if gvk.GroupVersion() == metav1beta1.SchemeGroupVersion || gvk.GroupVersion() == metav1.SchemeGroupVersion { switch gvk.Kind { case "Table": return scope.TableConvertor != nil &&