Merge pull request #77448 from smarterclayton/api_serve

Support meta.k8s.io/v1 Table and PartialObjectMetadata requests to the API

Kubernetes-commit: 274876ef9af526575f480c977f7dd7c4bb26e760
This commit is contained in:
Kubernetes Publisher 2019-05-10 21:30:37 -07:00
commit ecab80d4d8
6 changed files with 213 additions and 69 deletions

2
Godeps/Godeps.json generated
View File

@ -400,7 +400,7 @@
},
{
"ImportPath": "k8s.io/apimachinery",
"Rev": "ad85901afca0"
"Rev": "5b67e417bf61"
},
{
"ImportPath": "k8s.io/client-go",

4
go.mod
View File

@ -59,7 +59,7 @@ require (
gopkg.in/yaml.v2 v2.2.1
gotest.tools v2.2.0+incompatible // indirect
k8s.io/api v0.0.0-20190511023547-e63b5755afac
k8s.io/apimachinery v0.0.0-20190511023455-ad85901afca0
k8s.io/apimachinery v0.0.0-20190511063452-5b67e417bf61
k8s.io/client-go v0.0.0-20190511023711-c6f3777976ad
k8s.io/component-base v0.0.0-20190511024024-91ee9e34fdd1
k8s.io/klog v0.3.0
@ -75,7 +75,7 @@ replace (
golang.org/x/sys => golang.org/x/sys v0.0.0-20190209173611-3b5209105503
golang.org/x/tools => golang.org/x/tools v0.0.0-20190313210603-aa82965741a9
k8s.io/api => k8s.io/api v0.0.0-20190511023547-e63b5755afac
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190511023455-ad85901afca0
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190511063452-5b67e417bf61
k8s.io/client-go => k8s.io/client-go v0.0.0-20190511023711-c6f3777976ad
k8s.io/component-base => k8s.io/component-base v0.0.0-20190511024024-91ee9e34fdd1
)

2
go.sum
View File

@ -193,7 +193,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
k8s.io/api v0.0.0-20190511023547-e63b5755afac/go.mod h1:f265Ep4XvHtyggfaaNhtP0AtAFilBaXq2fPjm5kYxwI=
k8s.io/apimachinery v0.0.0-20190511023455-ad85901afca0/go.mod h1:5CBnzrKYGHzv9ZsSKmQ8wHt4XI4/TUBPDwYM9FlZMyw=
k8s.io/apimachinery v0.0.0-20190511063452-5b67e417bf61/go.mod h1:5CBnzrKYGHzv9ZsSKmQ8wHt4XI4/TUBPDwYM9FlZMyw=
k8s.io/client-go v0.0.0-20190511023711-c6f3777976ad/go.mod h1:+kqLjErve3/VoGTdnrw4Lu8D315nxEVQs1QEq8/uJ2E=
k8s.io/component-base v0.0.0-20190511024024-91ee9e34fdd1/go.mod h1:hlLSedoHFjaibpkg18jYZ0v6lpuhbLAVfenuqtu3Hrk=
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=

View File

@ -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",

View File

@ -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
}

View File

@ -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 &&