Switch TableGenerator/TableConvertor interfaces to metav1

This commit is contained in:
Jordan Liggitt 2019-11-26 13:13:25 -05:00
parent 2e57e54fa6
commit 36eb250cbb
42 changed files with 818 additions and 683 deletions

View File

@ -12,7 +12,6 @@ go_library(
deps = [
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
],

View File

@ -30,7 +30,6 @@ go_test(
"//pkg/printers:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
@ -93,7 +92,6 @@ go_library(
"//staging/src/k8s.io/api/scheduling/v1:go_default_library",
"//staging/src/k8s.io/api/storage/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/printers/storage",
deps = [
"//pkg/printers:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
],
)

View File

@ -20,22 +20,22 @@ import (
"context"
"fmt"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/printers"
)
// TableConvertor struct - converts objects to metav1beta1.Table using printers.TableGenerator
// TableConvertor struct - converts objects to metav1.Table using printers.TableGenerator
type TableConvertor struct {
printers.TableGenerator
}
// ConvertToTable method - converts objects to metav1beta1.Table objects using TableGenerator
func (c TableConvertor) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
// ConvertToTable method - converts objects to metav1.Table objects using TableGenerator
func (c TableConvertor) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
noHeaders := false
if tableOptions != nil {
switch t := tableOptions.(type) {
case *metav1beta1.TableOptions:
case *metav1.TableOptions:
if t != nil {
noHeaders = t.NoHeaders
}

View File

@ -22,7 +22,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
)
@ -33,18 +32,18 @@ type GenerateOptions struct {
Wide bool
}
// TableGenerator - an interface for generating metav1beta1.Table provided a runtime.Object
// TableGenerator - an interface for generating metav1.Table provided a runtime.Object
type TableGenerator interface {
GenerateTable(obj runtime.Object, options GenerateOptions) (*metav1beta1.Table, error)
GenerateTable(obj runtime.Object, options GenerateOptions) (*metav1.Table, error)
}
// PrintHandler - interface to handle printing provided an array of metav1beta1.TableColumnDefinition
// PrintHandler - interface to handle printing provided an array of metav1.TableColumnDefinition
type PrintHandler interface {
TableHandler(columns []metav1beta1.TableColumnDefinition, printFunc interface{}) error
TableHandler(columns []metav1.TableColumnDefinition, printFunc interface{}) error
}
type handlerEntry struct {
columnDefinitions []metav1beta1.TableColumnDefinition
columnDefinitions []metav1.TableColumnDefinition
printFunc reflect.Value
args []reflect.Value
}
@ -77,7 +76,7 @@ func (h *HumanReadableGenerator) With(fns ...func(PrintHandler)) *HumanReadableG
// GenerateTable returns a table for the provided object, using the printer registered for that type. It returns
// a table that includes all of the information requested by options, but will not remove rows or columns. The
// caller is responsible for applying rules related to filtering rows or columns.
func (h *HumanReadableGenerator) GenerateTable(obj runtime.Object, options GenerateOptions) (*metav1beta1.Table, error) {
func (h *HumanReadableGenerator) GenerateTable(obj runtime.Object, options GenerateOptions) (*metav1.Table, error) {
t := reflect.TypeOf(obj)
handler, ok := h.handlerMap[t]
if !ok {
@ -90,11 +89,11 @@ func (h *HumanReadableGenerator) GenerateTable(obj runtime.Object, options Gener
return nil, results[1].Interface().(error)
}
var columns []metav1beta1.TableColumnDefinition
var columns []metav1.TableColumnDefinition
if !options.NoHeaders {
columns = handler.columnDefinitions
if !options.Wide {
columns = make([]metav1beta1.TableColumnDefinition, 0, len(handler.columnDefinitions))
columns = make([]metav1.TableColumnDefinition, 0, len(handler.columnDefinitions))
for i := range handler.columnDefinitions {
if handler.columnDefinitions[i].Priority != 0 {
continue
@ -103,12 +102,12 @@ func (h *HumanReadableGenerator) GenerateTable(obj runtime.Object, options Gener
}
}
}
table := &metav1beta1.Table{
table := &metav1.Table{
ListMeta: metav1.ListMeta{
ResourceVersion: "",
},
ColumnDefinitions: columns,
Rows: results[0].Interface().([]metav1beta1.TableRow),
Rows: results[0].Interface().([]metav1.TableRow),
}
if m, err := meta.ListAccessor(obj); err == nil {
table.ResourceVersion = m.GetResourceVersion()
@ -126,7 +125,7 @@ func (h *HumanReadableGenerator) GenerateTable(obj runtime.Object, options Gener
// TableHandler adds a print handler with a given set of columns to HumanReadableGenerator instance.
// See ValidateRowPrintHandlerFunc for required method signature.
func (h *HumanReadableGenerator) TableHandler(columnDefinitions []metav1beta1.TableColumnDefinition, printFunc interface{}) error {
func (h *HumanReadableGenerator) TableHandler(columnDefinitions []metav1.TableColumnDefinition, printFunc interface{}) error {
printFuncValue := reflect.ValueOf(printFunc)
if err := ValidateRowPrintHandlerFunc(printFuncValue); err != nil {
utilruntime.HandleError(fmt.Errorf("unable to register print function: %v", err))
@ -150,7 +149,7 @@ func (h *HumanReadableGenerator) TableHandler(columnDefinitions []metav1beta1.Ta
// ValidateRowPrintHandlerFunc validates print handler signature.
// printFunc is the function that will be called to print an object.
// It must be of the following type:
// func printFunc(object ObjectType, options GenerateOptions) ([]metav1beta1.TableRow, error)
// func printFunc(object ObjectType, options GenerateOptions) ([]metav1.TableRow, error)
// where ObjectType is the type of the object that will be printed, and the first
// return value is an array of rows, with each row containing a number of cells that
// match the number of columns defined for that printer function.
@ -164,10 +163,10 @@ func ValidateRowPrintHandlerFunc(printFunc reflect.Value) error {
"Must accept 2 parameters and return 2 value.")
}
if funcType.In(1) != reflect.TypeOf((*GenerateOptions)(nil)).Elem() ||
funcType.Out(0) != reflect.TypeOf((*[]metav1beta1.TableRow)(nil)).Elem() ||
funcType.Out(0) != reflect.TypeOf((*[]metav1.TableRow)(nil)).Elem() ||
funcType.Out(1) != reflect.TypeOf((*error)(nil)).Elem() {
return fmt.Errorf("invalid print handler. The expected signature is: "+
"func handler(obj %v, options GenerateOptions) ([]metav1beta1.TableRow, error)", funcType.In(0))
"func handler(obj %v, options GenerateOptions) ([]metav1.TableRow, error)", funcType.In(0))
}
return nil
}

View File

@ -39,7 +39,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",

View File

@ -23,7 +23,6 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/registry/generic"
@ -273,7 +272,7 @@ func shouldHaveDeleteDependentsFinalizer(options *metav1.DeleteOptions, haveDele
return haveDeleteDependentsFinalizer
}
func (e *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
func (e *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
return e.store.ConvertToTable(ctx, object, tableOptions)
}

View File

@ -24,7 +24,6 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",

View File

@ -22,11 +22,10 @@ import (
"testing"
"time"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
@ -430,7 +429,7 @@ func TestConvertToTableList(t *testing.T) {
defer storage.Store.DestroyFunc()
ctx := genericapirequest.NewDefaultContext()
columns := []metav1beta1.TableColumnDefinition{
columns := []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "Ready", Type: "string", Description: "The aggregate readiness state of this pod for accepting traffic."},
{Name: "Status", Type: "string", Description: "The aggregate status of the containers in this pod."},
@ -522,7 +521,7 @@ func TestConvertToTableList(t *testing.T) {
testCases := []struct {
in runtime.Object
out *metav1beta1.Table
out *metav1.Table
err bool
}{
{
@ -531,31 +530,31 @@ func TestConvertToTableList(t *testing.T) {
},
{
in: &api.Pod{},
out: &metav1beta1.Table{
out: &metav1.Table{
ColumnDefinitions: columns,
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"", "0/0", "", int64(0), "<unknown>", "<none>", "<none>", "<none>", "<none>"}, Object: runtime.RawExtension{Object: &api.Pod{}}},
},
},
},
{
in: pod1,
out: &metav1beta1.Table{
out: &metav1.Table{
ColumnDefinitions: columns,
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo", "1/2", "Pending", int64(10), "370d", "10.1.2.3", "test-node", "nominated-node", "1/2"}, Object: runtime.RawExtension{Object: pod1}},
},
},
},
{
in: &api.PodList{},
out: &metav1beta1.Table{ColumnDefinitions: columns},
out: &metav1.Table{ColumnDefinitions: columns},
},
{
in: multiIPsPod,
out: &metav1beta1.Table{
out: &metav1.Table{
ColumnDefinitions: columns,
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo", "1/2", "Pending", int64(10), "370d", "10.1.2.3", "test-node", "nominated-node", "1/2"}, Object: runtime.RawExtension{Object: multiIPsPod}},
},
},

View File

@ -26,7 +26,6 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
@ -67,7 +66,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",

View File

@ -28,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
utilnet "k8s.io/apimachinery/pkg/util/net"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@ -81,7 +80,6 @@ type ServiceStorage interface {
rest.CreaterUpdater
rest.GracefulDeleter
rest.Watcher
rest.TableConvertor
rest.Exporter
rest.StorageVersionProvider
}
@ -550,7 +548,7 @@ func (rs *REST) ResourceLocation(ctx context.Context, id string) (*url.URL, http
return nil, nil, errors.NewServiceUnavailable(fmt.Sprintf("no endpoints available for service %q", id))
}
func (r *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
func (r *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
return r.services.ConvertToTable(ctx, object, tableOptions)
}

View File

@ -28,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
utilnet "k8s.io/apimachinery/pkg/util/net"
@ -155,7 +154,7 @@ func (s *serviceStorage) Watch(ctx context.Context, options *metainternalversion
panic("not implemented")
}
func (s *serviceStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
func (s *serviceStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
panic("not implemented")
}

View File

@ -80,7 +80,6 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",

View File

@ -30,7 +30,6 @@ import (
metainternal "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
@ -266,7 +265,7 @@ func TestColumns(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
tbl, err := storage.CustomResource.ConvertToTable(ctx, gottenList, &metav1beta1.TableOptions{})
tbl, err := storage.CustomResource.ConvertToTable(ctx, gottenList, &metav1.TableOptions{})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

View File

@ -11,7 +11,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta/table:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
"//staging/src/k8s.io/client-go/util/jsonpath:go_default_library",

View File

@ -27,7 +27,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metatable "k8s.io/apimachinery/pkg/api/meta/table"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/client-go/util/jsonpath"
@ -38,7 +37,7 @@ var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
// New creates a new table convertor for the provided CRD column definition. If the printer definition cannot be parsed,
// error will be returned along with a default table convertor.
func New(crdColumns []apiextensions.CustomResourceColumnDefinition) (rest.TableConvertor, error) {
headers := []metav1beta1.TableColumnDefinition{
headers := []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
}
c := &convertor{
@ -58,7 +57,7 @@ func New(crdColumns []apiextensions.CustomResourceColumnDefinition) (rest.TableC
}
c.additionalColumns = append(c.additionalColumns, path)
c.headers = append(c.headers, metav1beta1.TableColumnDefinition{
c.headers = append(c.headers, metav1.TableColumnDefinition{
Name: col.Name,
Type: col.Type,
Format: col.Format,
@ -71,13 +70,13 @@ func New(crdColumns []apiextensions.CustomResourceColumnDefinition) (rest.TableC
}
type convertor struct {
headers []metav1beta1.TableColumnDefinition
headers []metav1.TableColumnDefinition
additionalColumns []*jsonpath.JSONPath
}
func (c *convertor) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
table := &metav1beta1.Table{}
opt, ok := tableOptions.(*metav1beta1.TableOptions)
func (c *convertor) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
table := &metav1.Table{}
opt, ok := tableOptions.(*metav1.TableOptions)
noHeaders := ok && opt != nil && opt.NoHeaders
if !noHeaders {
table.ColumnDefinitions = c.headers

View File

@ -76,7 +76,7 @@ func Test_cellForJSONValue(t *testing.T) {
func Test_convertor_ConvertToTable(t *testing.T) {
type fields struct {
headers []metav1beta1.TableColumnDefinition
headers []metav1.TableColumnDefinition
additionalColumns []*jsonpath.JSONPath
}
type args struct {
@ -88,13 +88,13 @@ func Test_convertor_ConvertToTable(t *testing.T) {
name string
fields fields
args args
want *metav1beta1.Table
want *metav1.Table
wantErr bool
}{
{
name: "Return table for object",
fields: fields{
headers: []metav1beta1.TableColumnDefinition{{Name: "name", Type: "string"}},
headers: []metav1.TableColumnDefinition{{Name: "name", Type: "string"}},
},
args: args{
obj: &metav1beta1.PartialObjectMetadata{
@ -102,9 +102,9 @@ func Test_convertor_ConvertToTable(t *testing.T) {
},
tableOptions: nil,
},
want: &metav1beta1.Table{
ColumnDefinitions: []metav1beta1.TableColumnDefinition{{Name: "name", Type: "string"}},
Rows: []metav1beta1.TableRow{
want: &metav1.Table{
ColumnDefinitions: []metav1.TableColumnDefinition{{Name: "name", Type: "string"}},
Rows: []metav1.TableRow{
{
Cells: []interface{}{"blah"},
Object: runtime.RawExtension{
@ -119,7 +119,7 @@ func Test_convertor_ConvertToTable(t *testing.T) {
{
name: "Return table for list",
fields: fields{
headers: []metav1beta1.TableColumnDefinition{{Name: "name", Type: "string"}},
headers: []metav1.TableColumnDefinition{{Name: "name", Type: "string"}},
},
args: args{
obj: &metav1beta1.PartialObjectMetadataList{
@ -130,9 +130,9 @@ func Test_convertor_ConvertToTable(t *testing.T) {
},
tableOptions: nil,
},
want: &metav1beta1.Table{
ColumnDefinitions: []metav1beta1.TableColumnDefinition{{Name: "name", Type: "string"}},
Rows: []metav1beta1.TableRow{
want: &metav1.Table{
ColumnDefinitions: []metav1.TableColumnDefinition{{Name: "name", Type: "string"}},
Rows: []metav1.TableRow{
{
Cells: []interface{}{"blah"},
Object: runtime.RawExtension{
@ -155,17 +155,17 @@ func Test_convertor_ConvertToTable(t *testing.T) {
{
name: "Accept TableOptions",
fields: fields{
headers: []metav1beta1.TableColumnDefinition{{Name: "name", Type: "string"}},
headers: []metav1.TableColumnDefinition{{Name: "name", Type: "string"}},
},
args: args{
obj: &metav1beta1.PartialObjectMetadata{
ObjectMeta: metav1.ObjectMeta{Name: "blah", CreationTimestamp: metav1.NewTime(time.Unix(1, 0))},
},
tableOptions: &metav1beta1.TableOptions{},
tableOptions: &metav1.TableOptions{},
},
want: &metav1beta1.Table{
ColumnDefinitions: []metav1beta1.TableColumnDefinition{{Name: "name", Type: "string"}},
Rows: []metav1beta1.TableRow{
want: &metav1.Table{
ColumnDefinitions: []metav1.TableColumnDefinition{{Name: "name", Type: "string"}},
Rows: []metav1.TableRow{
{
Cells: []interface{}{"blah"},
Object: runtime.RawExtension{
@ -180,16 +180,16 @@ func Test_convertor_ConvertToTable(t *testing.T) {
{
name: "Omit headers from TableOptions",
fields: fields{
headers: []metav1beta1.TableColumnDefinition{{Name: "name", Type: "string"}},
headers: []metav1.TableColumnDefinition{{Name: "name", Type: "string"}},
},
args: args{
obj: &metav1beta1.PartialObjectMetadata{
ObjectMeta: metav1.ObjectMeta{Name: "blah", CreationTimestamp: metav1.NewTime(time.Unix(1, 0))},
},
tableOptions: &metav1beta1.TableOptions{NoHeaders: true},
tableOptions: &metav1.TableOptions{NoHeaders: true},
},
want: &metav1beta1.Table{
Rows: []metav1beta1.TableRow{
want: &metav1.Table{
Rows: []metav1.TableRow{
{
Cells: []interface{}{"blah"},
Object: runtime.RawExtension{

View File

@ -158,97 +158,198 @@ func TestTableGet(t *testing.T) {
t.Fatal(err)
}
ret, err := crRestClient.Get().
Resource(crd.Spec.Names.Plural).
SetHeader("Accept", fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName)).
VersionedParams(&metav1beta1.TableOptions{}, parameterCodec).
Do().
Get()
if err != nil {
t.Fatalf("failed to list %v resources: %v", gvk, err)
}
tbl, ok := ret.(*metav1beta1.Table)
if !ok {
t.Fatalf("expected metav1beta1.Table, got %T", ret)
}
t.Logf("%v table list: %#v", gvk, tbl)
columns, err := getColumnsForVersion(crd, v.Name)
if err != nil {
t.Fatal(err)
}
expectColumnNum := len(columns) + 1
if got, expected := len(tbl.ColumnDefinitions), expectColumnNum; got != expected {
t.Errorf("expected %d headers, got %d", expected, got)
} else {
age := metav1beta1.TableColumnDefinition{Name: "Age", Type: "date", Format: "", Description: "Custom resource definition column (in JSONPath format): .metadata.creationTimestamp", Priority: 0}
if got, expected := tbl.ColumnDefinitions[1], age; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
// metav1beta1 table
{
ret, err := crRestClient.Get().
Resource(crd.Spec.Names.Plural).
SetHeader("Accept", fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName)).
VersionedParams(&metav1beta1.TableOptions{}, parameterCodec).
Do().
Get()
if err != nil {
t.Fatalf("failed to list %v resources: %v", gvk, err)
}
alpha := metav1beta1.TableColumnDefinition{Name: "Alpha", Type: "string", Format: "", Description: "Custom resource definition column (in JSONPath format): .spec.alpha", Priority: 0}
if got, expected := tbl.ColumnDefinitions[2], alpha; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
tbl, ok := ret.(*metav1beta1.Table)
if !ok {
t.Fatalf("expected metav1beta1.Table, got %T", ret)
}
t.Logf("%v table list: %#v", gvk, tbl)
beta := metav1beta1.TableColumnDefinition{Name: "Beta", Type: "integer", Format: "int64", Description: "the beta field", Priority: 42}
if got, expected := tbl.ColumnDefinitions[3], beta; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
columns, err := getColumnsForVersion(crd, v.Name)
if err != nil {
t.Fatal(err)
}
gamma := metav1beta1.TableColumnDefinition{Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values"}
if got, expected := tbl.ColumnDefinitions[4], gamma; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
epsilon := metav1beta1.TableColumnDefinition{Name: "Epsilon", Type: "string", Description: "an array of integers as string"}
if got, expected := tbl.ColumnDefinitions[5], epsilon; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
// Validate extra column for v1
if i == 1 {
zeta := metav1beta1.TableColumnDefinition{Name: "Zeta", Type: "integer", Format: "int64", Description: "the zeta field", Priority: 42}
if got, expected := tbl.ColumnDefinitions[6], zeta; got != expected {
expectColumnNum := len(columns) + 1
if got, expected := len(tbl.ColumnDefinitions), expectColumnNum; got != expected {
t.Errorf("expected %d headers, got %d", expected, got)
} else {
age := metav1beta1.TableColumnDefinition{Name: "Age", Type: "date", Format: "", Description: "Custom resource definition column (in JSONPath format): .metadata.creationTimestamp", Priority: 0}
if got, expected := tbl.ColumnDefinitions[1], age; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
}
}
if got, expected := len(tbl.Rows), 1; got != expected {
t.Errorf("expected %d rows, got %d", expected, got)
} else if got, expected := len(tbl.Rows[0].Cells), expectColumnNum; got != expected {
t.Errorf("expected %d cells, got %d", expected, got)
} else {
if got, expected := tbl.Rows[0].Cells[0], "foo"; got != expected {
t.Errorf("expected cell[0] to equal %q, got %q", expected, got)
}
if s, ok := tbl.Rows[0].Cells[1].(string); !ok {
t.Errorf("expected cell[1] to be a string, got: %#v", tbl.Rows[0].Cells[1])
} else {
dur, err := time.ParseDuration(s)
if err != nil {
t.Errorf("expected cell[1] to be a duration: %v", err)
} else if abs(dur.Seconds()) > 30.0 {
t.Errorf("expected cell[1] to be a small age, but got: %v", dur)
alpha := metav1beta1.TableColumnDefinition{Name: "Alpha", Type: "string", Format: "", Description: "Custom resource definition column (in JSONPath format): .spec.alpha", Priority: 0}
if got, expected := tbl.ColumnDefinitions[2], alpha; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
beta := metav1beta1.TableColumnDefinition{Name: "Beta", Type: "integer", Format: "int64", Description: "the beta field", Priority: 42}
if got, expected := tbl.ColumnDefinitions[3], beta; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
gamma := metav1beta1.TableColumnDefinition{Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values"}
if got, expected := tbl.ColumnDefinitions[4], gamma; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
epsilon := metav1beta1.TableColumnDefinition{Name: "Epsilon", Type: "string", Description: "an array of integers as string"}
if got, expected := tbl.ColumnDefinitions[5], epsilon; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
// Validate extra column for v1
if i == 1 {
zeta := metav1beta1.TableColumnDefinition{Name: "Zeta", Type: "integer", Format: "int64", Description: "the zeta field", Priority: 42}
if got, expected := tbl.ColumnDefinitions[6], zeta; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
}
}
if got, expected := tbl.Rows[0].Cells[2], "foo_123"; got != expected {
t.Errorf("expected cell[2] to equal %q, got %q", expected, got)
if got, expected := len(tbl.Rows), 1; got != expected {
t.Errorf("expected %d rows, got %d", expected, got)
} else if got, expected := len(tbl.Rows[0].Cells), expectColumnNum; got != expected {
t.Errorf("expected %d cells, got %d", expected, got)
} else {
if got, expected := tbl.Rows[0].Cells[0], "foo"; got != expected {
t.Errorf("expected cell[0] to equal %q, got %q", expected, got)
}
if s, ok := tbl.Rows[0].Cells[1].(string); !ok {
t.Errorf("expected cell[1] to be a string, got: %#v", tbl.Rows[0].Cells[1])
} else {
dur, err := time.ParseDuration(s)
if err != nil {
t.Errorf("expected cell[1] to be a duration: %v", err)
} else if abs(dur.Seconds()) > 30.0 {
t.Errorf("expected cell[1] to be a small age, but got: %v", dur)
}
}
if got, expected := tbl.Rows[0].Cells[2], "foo_123"; got != expected {
t.Errorf("expected cell[2] to equal %q, got %q", expected, got)
}
if got, expected := tbl.Rows[0].Cells[3], int64(10); got != expected {
t.Errorf("expected cell[3] to equal %#v, got %#v", expected, got)
}
if got, expected := tbl.Rows[0].Cells[4], interface{}(nil); got != expected {
t.Errorf("expected cell[4] to equal %#v although the type does not match the column, got %#v", expected, got)
}
if got, expected := tbl.Rows[0].Cells[5], "[1 2 3]"; got != expected {
t.Errorf("expected cell[5] to equal %q, got %q", expected, got)
}
// Validate extra column for v1
if i == 1 {
if got, expected := tbl.Rows[0].Cells[6], int64(5); got != expected {
t.Errorf("expected cell[6] to equal %q, got %q", expected, got)
}
}
}
if got, expected := tbl.Rows[0].Cells[3], int64(10); got != expected {
t.Errorf("expected cell[3] to equal %#v, got %#v", expected, got)
}
// metav1 table
{
ret, err := crRestClient.Get().
Resource(crd.Spec.Names.Plural).
SetHeader("Accept", fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", metav1.SchemeGroupVersion.Version, metav1.GroupName)).
VersionedParams(&metav1.TableOptions{}, parameterCodec).
Do().
Get()
if err != nil {
t.Fatalf("failed to list %v resources: %v", gvk, err)
}
if got, expected := tbl.Rows[0].Cells[4], interface{}(nil); got != expected {
t.Errorf("expected cell[4] to equal %#v although the type does not match the column, got %#v", expected, got)
tbl, ok := ret.(*metav1.Table)
if !ok {
t.Fatalf("expected metav1.Table, got %T", ret)
}
if got, expected := tbl.Rows[0].Cells[5], "[1 2 3]"; got != expected {
t.Errorf("expected cell[5] to equal %q, got %q", expected, got)
t.Logf("%v table list: %#v", gvk, tbl)
columns, err := getColumnsForVersion(crd, v.Name)
if err != nil {
t.Fatal(err)
}
// Validate extra column for v1
if i == 1 {
if got, expected := tbl.Rows[0].Cells[6], int64(5); got != expected {
t.Errorf("expected cell[6] to equal %q, got %q", expected, got)
expectColumnNum := len(columns) + 1
if got, expected := len(tbl.ColumnDefinitions), expectColumnNum; got != expected {
t.Errorf("expected %d headers, got %d", expected, got)
} else {
age := metav1.TableColumnDefinition{Name: "Age", Type: "date", Format: "", Description: "Custom resource definition column (in JSONPath format): .metadata.creationTimestamp", Priority: 0}
if got, expected := tbl.ColumnDefinitions[1], age; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
alpha := metav1.TableColumnDefinition{Name: "Alpha", Type: "string", Format: "", Description: "Custom resource definition column (in JSONPath format): .spec.alpha", Priority: 0}
if got, expected := tbl.ColumnDefinitions[2], alpha; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
beta := metav1.TableColumnDefinition{Name: "Beta", Type: "integer", Format: "int64", Description: "the beta field", Priority: 42}
if got, expected := tbl.ColumnDefinitions[3], beta; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
gamma := metav1.TableColumnDefinition{Name: "Gamma", Type: "integer", Description: "a column with wrongly typed values"}
if got, expected := tbl.ColumnDefinitions[4], gamma; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
epsilon := metav1.TableColumnDefinition{Name: "Epsilon", Type: "string", Description: "an array of integers as string"}
if got, expected := tbl.ColumnDefinitions[5], epsilon; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
// Validate extra column for v1
if i == 1 {
zeta := metav1.TableColumnDefinition{Name: "Zeta", Type: "integer", Format: "int64", Description: "the zeta field", Priority: 42}
if got, expected := tbl.ColumnDefinitions[6], zeta; got != expected {
t.Errorf("expected column definition %#v, got %#v", expected, got)
}
}
}
if got, expected := len(tbl.Rows), 1; got != expected {
t.Errorf("expected %d rows, got %d", expected, got)
} else if got, expected := len(tbl.Rows[0].Cells), expectColumnNum; got != expected {
t.Errorf("expected %d cells, got %d", expected, got)
} else {
if got, expected := tbl.Rows[0].Cells[0], "foo"; got != expected {
t.Errorf("expected cell[0] to equal %q, got %q", expected, got)
}
if s, ok := tbl.Rows[0].Cells[1].(string); !ok {
t.Errorf("expected cell[1] to be a string, got: %#v", tbl.Rows[0].Cells[1])
} else {
dur, err := time.ParseDuration(s)
if err != nil {
t.Errorf("expected cell[1] to be a duration: %v", err)
} else if abs(dur.Seconds()) > 30.0 {
t.Errorf("expected cell[1] to be a small age, but got: %v", dur)
}
}
if got, expected := tbl.Rows[0].Cells[2], "foo_123"; got != expected {
t.Errorf("expected cell[2] to equal %q, got %q", expected, got)
}
if got, expected := tbl.Rows[0].Cells[3], int64(10); got != expected {
t.Errorf("expected cell[3] to equal %#v, got %#v", expected, got)
}
if got, expected := tbl.Rows[0].Cells[4], interface{}(nil); got != expected {
t.Errorf("expected cell[4] to equal %#v although the type does not match the column, got %#v", expected, got)
}
if got, expected := tbl.Rows[0].Cells[5], "[1 2 3]"; got != expected {
t.Errorf("expected cell[5] to equal %q, got %q", expected, got)
}
// Validate extra column for v1
if i == 1 {
if got, expected := tbl.Rows[0].Cells[6], int64(5); got != expected {
t.Errorf("expected cell[6] to equal %q, got %q", expected, got)
}
}
}
}

View File

@ -9,7 +9,6 @@ go_library(
deps = [
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
],

View File

@ -21,16 +21,15 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/duration"
)
// MetaToTableRow converts a list or object into one or more table rows. The provided rowFn is invoked for
// each accessed item, with name and age being passed to each.
func MetaToTableRow(obj runtime.Object, rowFn func(obj runtime.Object, m metav1.Object, name, age string) ([]interface{}, error)) ([]metav1beta1.TableRow, error) {
func MetaToTableRow(obj runtime.Object, rowFn func(obj runtime.Object, m metav1.Object, name, age string) ([]interface{}, error)) ([]metav1.TableRow, error) {
if meta.IsListType(obj) {
rows := make([]metav1beta1.TableRow, 0, 16)
rows := make([]metav1.TableRow, 0, 16)
err := meta.EachListItem(obj, func(obj runtime.Object) error {
nestedRows, err := MetaToTableRow(obj, rowFn)
if err != nil {
@ -45,12 +44,12 @@ func MetaToTableRow(obj runtime.Object, rowFn func(obj runtime.Object, m metav1.
return rows, nil
}
rows := make([]metav1beta1.TableRow, 0, 1)
rows := make([]metav1.TableRow, 0, 1)
m, err := meta.Accessor(obj)
if err != nil {
return nil, err
}
row := metav1beta1.TableRow{
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
row.Cells, err = rowFn(obj, m, m.GetName(), ConvertToHumanReadableDateType(m.GetCreationTimestamp()))

View File

@ -71,8 +71,8 @@ func addToGroupVersion(scheme *runtime.Scheme) error {
&metav1.UpdateOptions{},
)
scheme.AddKnownTypes(SchemeGroupVersion,
&metav1beta1.Table{},
&metav1beta1.TableOptions{},
&metav1.Table{},
&metav1.TableOptions{},
&metav1beta1.PartialObjectMetadata{},
&metav1beta1.PartialObjectMetadataList{},
)

View File

@ -8,7 +8,6 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
],
)

View File

@ -18,12 +18,11 @@ package validation
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/util/validation/field"
)
// ValidateTableOptions returns any invalid flags on TableOptions.
func ValidateTableOptions(opts *metav1beta1.TableOptions) field.ErrorList {
func ValidateTableOptions(opts *metav1.TableOptions) field.ErrorList {
var allErrs field.ErrorList
switch opts.IncludeObject {
case metav1.IncludeMetadata, metav1.IncludeNone, metav1.IncludeObject, "":

View File

@ -377,7 +377,7 @@ func (storage *SimpleRESTStorage) Export(ctx context.Context, name string, opts
return obj, storage.errors["export"]
}
func (storage *SimpleRESTStorage) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
func (storage *SimpleRESTStorage) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
return rest.NewDefaultTableConvertor(schema.GroupResource{Resource: "simple"}).ConvertToTable(ctx, obj, tableOptions)
}
@ -895,6 +895,10 @@ func (OnlyGetRESTStorage) List(ctx context.Context, options *metainternalversion
return nil, nil
}
func (OnlyGetRESTStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
return nil, nil
}
// TestSomeUnimplementedRESTStorage ensures that if a rest.Storage does
// not implement a given method, that it is literally not registered
// with the server. We need to have at least one verb supported inorder
@ -1900,7 +1904,7 @@ func TestGetTable(t *testing.T) {
accept string
params url.Values
pretty bool
expected *metav1beta1.Table
expected *metav1.Table
statusCode int
item bool
}{
@ -1935,14 +1939,14 @@ func TestGetTable(t *testing.T) {
{
item: true,
accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io",
expected: &metav1beta1.Table{
expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"},
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
},
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}},
},
},
@ -1953,14 +1957,14 @@ func TestGetTable(t *testing.T) {
runtime.ContentTypeProtobuf + ";as=Table;v=v1beta1;g=meta.k8s.io",
"application/json;as=Table;v=v1beta1;g=meta.k8s.io",
}, ","),
expected: &metav1beta1.Table{
expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"},
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
},
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}},
},
},
@ -1969,14 +1973,14 @@ func TestGetTable(t *testing.T) {
item: true,
accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io",
params: url.Values{"includeObject": []string{"Metadata"}},
expected: &metav1beta1.Table{
expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"},
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
},
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}},
},
},
@ -1984,14 +1988,14 @@ func TestGetTable(t *testing.T) {
{
accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io",
params: url.Values{"includeObject": []string{"Metadata"}},
expected: &metav1beta1.Table{
expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/test/link"},
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
},
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", now.Time.UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedV1Beta1Body}},
},
},
@ -2051,7 +2055,7 @@ func TestGetTable(t *testing.T) {
if resp.StatusCode != http.StatusOK {
t.Errorf("%d: unexpected response: %#v", i, resp)
}
var itemOut metav1beta1.Table
var itemOut metav1.Table
body, err := extractBody(resp, &itemOut)
if err != nil {
t.Fatal(err)
@ -2117,14 +2121,14 @@ func TestWatchTable(t *testing.T) {
{
Type: "ADDED",
Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1beta1.Table{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"},
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
},
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}},
},
}))),
@ -2142,14 +2146,14 @@ func TestWatchTable(t *testing.T) {
{
Type: "ADDED",
Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1beta1.Table{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"},
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
},
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}},
},
}))),
@ -2158,10 +2162,10 @@ func TestWatchTable(t *testing.T) {
{
Type: "MODIFIED",
Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1beta1.Table{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"},
Rows: []metav1beta1.TableRow{
Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}},
},
}))),
@ -2182,7 +2186,7 @@ func TestWatchTable(t *testing.T) {
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{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
},

View File

@ -74,7 +74,7 @@ func doTransformObject(ctx context.Context, obj runtime.Object, opts interface{}
return asPartialObjectMetadataList(obj, target.GroupVersion())
case target.Kind == "Table":
options, ok := opts.(*metav1beta1.TableOptions)
options, ok := opts.(*metav1.TableOptions)
if !ok {
return nil, fmt.Errorf("unexpected TableOptions, got %T", opts)
}
@ -93,8 +93,8 @@ func optionsForTransform(mediaType negotiation.MediaTypeOptions, req *http.Reque
switch target := mediaType.Convert; {
case target == nil:
case target.Kind == "Table" && (target.GroupVersion() == metav1beta1.SchemeGroupVersion || target.GroupVersion() == metav1.SchemeGroupVersion):
opts := &metav1beta1.TableOptions{}
if err := metainternalversionscheme.ParameterCodec.DecodeParameters(req.URL.Query(), metav1beta1.SchemeGroupVersion, opts); err != nil {
opts := &metav1.TableOptions{}
if err := metainternalversionscheme.ParameterCodec.DecodeParameters(req.URL.Query(), metav1.SchemeGroupVersion, opts); err != nil {
return nil, err
}
switch errs := validation.ValidateTableOptions(opts); len(errs) {
@ -159,7 +159,7 @@ func (e errNotAcceptable) Status() metav1.Status {
}
}
func asTable(ctx context.Context, result runtime.Object, opts *metav1beta1.TableOptions, scope *RequestScope, groupVersion schema.GroupVersion) (runtime.Object, error) {
func asTable(ctx context.Context, result runtime.Object, opts *metav1.TableOptions, scope *RequestScope, groupVersion schema.GroupVersion) (runtime.Object, error) {
switch groupVersion {
case metav1beta1.SchemeGroupVersion, metav1.SchemeGroupVersion:
default:

View File

@ -25,7 +25,6 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@ -125,7 +124,7 @@ func serveWatch(watcher watch.Interface, scope *RequestScope, mediaTypeOptions n
// When we are transformed to a table, use the table options as the state for whether we
// should print headers - on watch, we only want to print table headers on the first object
// and omit them on subsequent events.
if tableOptions, ok := options.(*metav1beta1.TableOptions); ok {
if tableOptions, ok := options.(*metav1.TableOptions); ok {
tableOptions.NoHeaders = true
}
return result

View File

@ -65,7 +65,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/validation/path:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",

View File

@ -29,7 +29,6 @@ import (
"k8s.io/apimachinery/pkg/api/validation/path"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
@ -1353,7 +1352,7 @@ func (e *Store) startObservingCount(period time.Duration) func() {
return func() { close(stopCh) }
}
func (e *Store) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
func (e *Store) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
if e.TableConvertor != nil {
return e.TableConvertor.ConvertToTable(ctx, object, tableOptions)
}

View File

@ -41,7 +41,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",

View File

@ -24,7 +24,6 @@ import (
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
@ -99,6 +98,8 @@ type Lister interface {
NewList() runtime.Object
// List selects resources in the storage which match to the selector. 'options' can be nil.
List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error)
// TableConvertor ensures all list implementers also implement table conversion
TableConvertor
}
// Exporter is an object that knows how to strip a RESTful resource for export. A store should implement this interface
@ -141,7 +142,7 @@ type GetterWithOptions interface {
}
type TableConvertor interface {
ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error)
ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error)
}
// GracefulDeleter knows how to pass deletion options to allow delayed deletion of a

View File

@ -24,7 +24,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
@ -40,14 +39,14 @@ func NewDefaultTableConvertor(resource schema.GroupResource) TableConvertor {
var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
func (c defaultTableConvertor) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
var table metav1beta1.Table
func (c defaultTableConvertor) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
var table metav1.Table
fn := func(obj runtime.Object) error {
m, err := meta.Accessor(obj)
if err != nil {
return errNotAcceptable{resource: c.qualifiedResource}
}
table.Rows = append(table.Rows, metav1beta1.TableRow{
table.Rows = append(table.Rows, metav1.TableRow{
Cells: []interface{}{m.GetName(), m.GetCreationTimestamp().Time.UTC().Format(time.RFC3339)},
Object: runtime.RawExtension{Object: obj},
})
@ -74,8 +73,8 @@ func (c defaultTableConvertor) ConvertToTable(ctx context.Context, object runtim
table.SelfLink = m.GetSelfLink()
}
}
if opt, ok := tableOptions.(*metav1beta1.TableOptions); !ok || !opt.NoHeaders {
table.ColumnDefinitions = []metav1beta1.TableColumnDefinition{
if opt, ok := tableOptions.(*metav1.TableOptions); !ok || !opt.NoHeaders {
table.ColumnDefinitions = []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
{Name: "Created At", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"]},
}

View File

@ -22,7 +22,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",

View File

@ -26,7 +26,6 @@ import (
"github.com/liggitt/tabwriter"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/duration"
@ -36,7 +35,7 @@ import (
var _ ResourcePrinter = &HumanReadablePrinter{}
type printHandler struct {
columnDefinitions []metav1beta1.TableColumnDefinition
columnDefinitions []metav1.TableColumnDefinition
printFunc reflect.Value
}
@ -46,7 +45,7 @@ var (
printFunc: reflect.ValueOf(printStatus),
}
statusColumnDefinitions = []metav1beta1.TableColumnDefinition{
statusColumnDefinitions = []metav1.TableColumnDefinition{
{Name: "Status", Type: "string"},
{Name: "Reason", Type: "string"},
{Name: "Message", Type: "string"},
@ -57,7 +56,7 @@ var (
printFunc: reflect.ValueOf(printObjectMeta),
}
objectMetaColumnDefinitions = []metav1beta1.TableColumnDefinition{
objectMetaColumnDefinitions = []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
}
@ -73,7 +72,7 @@ var (
type HumanReadablePrinter struct {
options PrintOptions
lastType interface{}
lastColumns []metav1beta1.TableColumnDefinition
lastColumns []metav1.TableColumnDefinition
printedHeaders bool
}
@ -110,7 +109,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
// Parameter "obj" is a table from server; print it.
// display tables following the rules of options
if table, ok := obj.(*metav1beta1.Table); ok {
if table, ok := obj.(*metav1.Table); ok {
// Do not print headers if this table has no column definitions, or they are the same as the last ones we printed
localOptions := h.options
if h.printedHeaders && (len(table.ColumnDefinitions) == 0 || reflect.DeepEqual(table.ColumnDefinitions, h.lastColumns)) {
@ -136,8 +135,8 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
}
if len(eventType) > 0 {
if err := addColumns(beginning, table,
[]metav1beta1.TableColumnDefinition{{Name: "Event", Type: "string"}},
[]cellValueFunc{func(metav1beta1.TableRow) (interface{}, error) { return formatEventType(eventType), nil }},
[]metav1.TableColumnDefinition{{Name: "Event", Type: "string"}},
[]cellValueFunc{func(metav1.TableRow) (interface{}, error) { return formatEventType(eventType), nil }},
); err != nil {
return err
}
@ -171,7 +170,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
// printTable prints a table to the provided output respecting the filtering rules for options
// for wide columns and filtered rows. It filters out rows that are Completed. You should call
// decorateTable if you receive a table from a remote server before calling printTable.
func printTable(table *metav1beta1.Table, output io.Writer, options PrintOptions) error {
func printTable(table *metav1.Table, output io.Writer, options PrintOptions) error {
if !options.NoHeaders {
// avoid printing headers if we have no rows to display
if len(table.Rows) == 0 {
@ -218,7 +217,7 @@ func printTable(table *metav1beta1.Table, output io.Writer, options PrintOptions
return nil
}
type cellValueFunc func(metav1beta1.TableRow) (interface{}, error)
type cellValueFunc func(metav1.TableRow) (interface{}, error)
type columnAddPosition int
@ -227,7 +226,7 @@ const (
end columnAddPosition = 2
)
func addColumns(pos columnAddPosition, table *metav1beta1.Table, columns []metav1beta1.TableColumnDefinition, valueFuncs []cellValueFunc) error {
func addColumns(pos columnAddPosition, table *metav1.Table, columns []metav1.TableColumnDefinition, valueFuncs []cellValueFunc) error {
if len(columns) != len(valueFuncs) {
return fmt.Errorf("cannot prepend columns, unmatched value functions")
}
@ -268,7 +267,7 @@ func addColumns(pos columnAddPosition, table *metav1beta1.Table, columns []metav
}
// All cells successfully computed, now replace columns and rows
newColumns := make([]metav1beta1.TableColumnDefinition, 0, len(columns)+len(table.ColumnDefinitions))
newColumns := make([]metav1.TableColumnDefinition, 0, len(columns)+len(table.ColumnDefinitions))
switch pos {
case beginning:
newColumns = append(newColumns, columns...)
@ -291,7 +290,7 @@ func addColumns(pos columnAddPosition, table *metav1beta1.Table, columns []metav
// namespace column. It will fill empty columns with nil (if the object
// does not expose metadata). It returns an error if the table cannot
// be decorated.
func decorateTable(table *metav1beta1.Table, options PrintOptions) error {
func decorateTable(table *metav1.Table, options PrintOptions) error {
width := len(table.ColumnDefinitions) + len(options.ColumnLabels)
if options.WithNamespace {
width++
@ -313,22 +312,22 @@ func decorateTable(table *metav1beta1.Table, options PrintOptions) error {
}
if width != len(table.ColumnDefinitions) {
columns = make([]metav1beta1.TableColumnDefinition, 0, width)
columns = make([]metav1.TableColumnDefinition, 0, width)
if options.WithNamespace {
columns = append(columns, metav1beta1.TableColumnDefinition{
columns = append(columns, metav1.TableColumnDefinition{
Name: "Namespace",
Type: "string",
})
}
columns = append(columns, table.ColumnDefinitions...)
for _, label := range formatLabelHeaders(options.ColumnLabels) {
columns = append(columns, metav1beta1.TableColumnDefinition{
columns = append(columns, metav1.TableColumnDefinition{
Name: label,
Type: "string",
})
}
if options.ShowLabels {
columns = append(columns, metav1beta1.TableColumnDefinition{
columns = append(columns, metav1.TableColumnDefinition{
Name: "Labels",
Type: "string",
})
@ -417,7 +416,7 @@ func printRowsForHandlerEntry(output io.Writer, handler *printHandler, eventType
}
if results[1].IsNil() {
rows := results[0].Interface().([]metav1beta1.TableRow)
rows := results[0].Interface().([]metav1.TableRow)
printRows(output, eventType, rows, options)
return nil
}
@ -439,7 +438,7 @@ func formatEventType(eventType string) string {
}
// printRows writes the provided rows to output.
func printRows(output io.Writer, eventType string, rows []metav1beta1.TableRow, options PrintOptions) {
func printRows(output io.Writer, eventType string, rows []metav1.TableRow, options PrintOptions) {
for _, row := range rows {
if len(eventType) > 0 {
fmt.Fprint(output, formatEventType(eventType))
@ -522,20 +521,20 @@ func appendLabelCells(values []interface{}, itemLabels map[string]string, opts P
return values
}
func printStatus(obj runtime.Object, options PrintOptions) ([]metav1beta1.TableRow, error) {
func printStatus(obj runtime.Object, options PrintOptions) ([]metav1.TableRow, error) {
status, ok := obj.(*metav1.Status)
if !ok {
return nil, fmt.Errorf("expected *v1.Status, got %T", obj)
}
return []metav1beta1.TableRow{{
return []metav1.TableRow{{
Object: runtime.RawExtension{Object: obj},
Cells: []interface{}{status.Status, status.Reason, status.Message},
}}, nil
}
func printObjectMeta(obj runtime.Object, options PrintOptions) ([]metav1beta1.TableRow, error) {
func printObjectMeta(obj runtime.Object, options PrintOptions) ([]metav1.TableRow, error) {
if meta.IsListType(obj) {
rows := make([]metav1beta1.TableRow, 0, 16)
rows := make([]metav1.TableRow, 0, 16)
err := meta.EachListItem(obj, func(obj runtime.Object) error {
nestedRows, err := printObjectMeta(obj, options)
if err != nil {
@ -550,12 +549,12 @@ func printObjectMeta(obj runtime.Object, options PrintOptions) ([]metav1beta1.Ta
return rows, nil
}
rows := make([]metav1beta1.TableRow, 0, 1)
rows := make([]metav1.TableRow, 0, 1)
m, err := meta.Accessor(obj)
if err != nil {
return nil, err
}
row := metav1beta1.TableRow{
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
row.Cells = append(row.Cells, m.GetName(), translateTimestampSince(m.GetCreationTimestamp()))

View File

@ -14,7 +14,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta/table:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library",

View File

@ -23,7 +23,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metatable "k8s.io/apimachinery/pkg/api/meta/table"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/generic"
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
@ -60,9 +59,9 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST
var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
// ConvertToTable implements the TableConvertor interface for REST.
func (c *REST) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
table := &metav1beta1.Table{
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
func (c *REST) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
table := &metav1.Table{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
{Name: "Service", Type: "string", Description: "The reference to the service that hosts this API endpoint."},
{Name: "Available", Type: "string", Description: "Whether this service is available."},

View File

@ -22,6 +22,7 @@ import (
"fmt"
"io"
"net/url"
"strings"
"github.com/spf13/cobra"
@ -351,7 +352,7 @@ func (r *RuntimeSorter) Sort() error {
return nil
}
if len(r.objects) == 1 {
_, isTable := r.objects[0].(*metav1beta1.Table)
_, isTable := r.objects[0].(*metav1.Table)
if !isTable {
return nil
}
@ -362,7 +363,7 @@ func (r *RuntimeSorter) Sort() error {
for _, obj := range r.objects {
switch t := obj.(type) {
case *metav1beta1.Table:
case *metav1.Table:
includesTable = true
if sorter, err := NewTableSorter(t, r.field); err != nil {
@ -433,11 +434,11 @@ func (o *GetOptions) transformRequests(req *rest.Request) {
return
}
group := metav1beta1.GroupName
version := metav1beta1.SchemeGroupVersion.Version
tableParam := fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", version, group)
req.SetHeader("Accept", tableParam)
req.SetHeader("Accept", strings.Join([]string{
fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1.SchemeGroupVersion.Version, metav1.GroupName),
fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName),
"application/json",
}, ","))
// if sorting, ensure we receive the full object in order to introspect its fields via jsonpath
if o.Sort {

View File

@ -18,6 +18,7 @@ package get
import (
"bytes"
"encoding/json"
encjson "encoding/json"
"fmt"
"io"
@ -267,6 +268,31 @@ foo 0/0 0 <unknown>
}
}
func TestGetV1TableObjects(t *testing.T) {
pods, _, _ := cmdtesting.TestData()
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
Resp: &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: podV1TableObjBody(codec, pods.Items[0])},
}
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdGet("kubectl", tf, streams)
cmd.SetOutput(buf)
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
func TestGetObjectsShowKind(t *testing.T) {
pods, _, _ := cmdtesting.TestData()
@ -2706,7 +2732,32 @@ var podColumns = []metav1.TableColumnDefinition{
// build a meta table response from a pod list
func podTableObjBody(codec runtime.Codec, pods ...corev1.Pod) io.ReadCloser {
table := &metav1beta1.Table{
TypeMeta: metav1.TypeMeta{APIVersion: "meta.k8s.io/v1beta1", Kind: "Table"},
ColumnDefinitions: podColumns,
}
for i := range pods {
b := bytes.NewBuffer(nil)
codec.Encode(&pods[i], b)
table.Rows = append(table.Rows, metav1beta1.TableRow{
Object: runtime.RawExtension{Raw: b.Bytes()},
Cells: []interface{}{pods[i].Name, "0/0", "", int64(0), "<unknown>", "<none>", "<none>", "<none>", "<none>"},
})
}
data, err := json.Marshal(table)
if err != nil {
panic(err)
}
if !strings.Contains(string(data), `"meta.k8s.io/v1beta1"`) {
panic("expected v1beta1, got " + string(data))
}
return cmdtesting.BytesBody(data)
}
// build a meta table response from a pod list
func podV1TableObjBody(codec runtime.Codec, pods ...corev1.Pod) io.ReadCloser {
table := &metav1.Table{
TypeMeta: metav1.TypeMeta{APIVersion: "meta.k8s.io/v1", Kind: "Table"},
ColumnDefinitions: podColumns,
}
for i := range pods {
@ -2717,7 +2768,14 @@ func podTableObjBody(codec runtime.Codec, pods ...corev1.Pod) io.ReadCloser {
Cells: []interface{}{pods[i].Name, "0/0", "", int64(0), "<unknown>", "<none>", "<none>", "<none>", "<none>"},
})
}
return cmdtesting.ObjBody(codec, table)
data, err := json.Marshal(table)
if err != nil {
panic(err)
}
if !strings.Contains(string(data), `"meta.k8s.io/v1"`) {
panic("expected v1, got " + string(data))
}
return cmdtesting.BytesBody(data)
}
// build meta table watch events from pod watch events

View File

@ -19,7 +19,7 @@ package get
import (
"io"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/printers"
)
@ -37,7 +37,7 @@ func (p *skipPrinter) PrintObj(obj runtime.Object, writer io.Writer) error {
return p.delegate.PrintObj(obj, writer)
}
table, isTable := obj.(*metav1beta1.Table)
table, isTable := obj.(*metav1.Table)
if !isTable {
return nil
}

View File

@ -28,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/client-go/util/jsonpath"
@ -46,7 +45,7 @@ type SortingPrinter struct {
}
func (s *SortingPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
if table, isTable := obj.(*metav1beta1.Table); isTable && len(table.Rows) > 1 {
if table, isTable := obj.(*metav1.Table); isTable && len(table.Rows) > 1 {
parsedField, err := RelaxedJSONPathExpression(s.SortField)
if err != nil {
parsedField = s.SortField
@ -322,7 +321,7 @@ func (r *RuntimeSort) OriginalPosition(ix int) int {
type TableSorter struct {
field string
obj *metav1beta1.Table
obj *metav1.Table
parsedRows [][][]reflect.Value
}
@ -361,7 +360,7 @@ func (t *TableSorter) Sort() error {
return nil
}
func NewTableSorter(table *metav1beta1.Table, field string) (*TableSorter, error) {
func NewTableSorter(table *metav1.Table, field string) (*TableSorter, error) {
var parsedRows [][][]reflect.Value
parser := jsonpath.New("sorting").AllowMissingKeys(true)

View File

@ -24,6 +24,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/klog"
)
@ -45,24 +46,26 @@ func (t *TablePrinter) PrintObj(obj runtime.Object, writer io.Writer) error {
return t.Delegate.PrintObj(obj, writer)
}
var recognizedTableVersions = map[schema.GroupVersionKind]bool{
metav1beta1.SchemeGroupVersion.WithKind("Table"): true,
metav1.SchemeGroupVersion.WithKind("Table"): true,
}
func decodeIntoTable(obj runtime.Object) (runtime.Object, error) {
event, isEvent := obj.(*metav1.WatchEvent)
if isEvent {
obj = event.Object.Object
}
if obj.GetObjectKind().GroupVersionKind().Group != metav1beta1.GroupName {
return nil, fmt.Errorf("attempt to decode non-Table object into a v1beta1.Table")
}
if obj.GetObjectKind().GroupVersionKind().Kind != "Table" {
return nil, fmt.Errorf("attempt to decode non-Table object into a v1beta1.Table")
if !recognizedTableVersions[obj.GetObjectKind().GroupVersionKind()] {
return nil, fmt.Errorf("attempt to decode non-Table object")
}
unstr, ok := obj.(*unstructured.Unstructured)
if !ok {
return nil, fmt.Errorf("attempt to decode non-Unstructured object")
}
table := &metav1beta1.Table{}
table := &metav1.Table{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstr.Object, table); err != nil {
return nil, err
}