diff --git a/pkg/registry/auditregistration/auditsink/storage/BUILD b/pkg/registry/auditregistration/auditsink/storage/BUILD index daa0d67de05..0c58422bef7 100644 --- a/pkg/registry/auditregistration/auditsink/storage/BUILD +++ b/pkg/registry/auditregistration/auditsink/storage/BUILD @@ -11,6 +11,7 @@ go_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", + "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", ], ) diff --git a/pkg/registry/auditregistration/auditsink/storage/storage.go b/pkg/registry/auditregistration/auditsink/storage/storage.go index 2ef0b5ee6b8..a2ba834c7f7 100644 --- a/pkg/registry/auditregistration/auditsink/storage/storage.go +++ b/pkg/registry/auditregistration/auditsink/storage/storage.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/apiserver/pkg/registry/rest" "k8s.io/kubernetes/pkg/apis/auditregistration" auditstrategy "k8s.io/kubernetes/pkg/registry/auditregistration/auditsink" ) @@ -42,6 +43,9 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { CreateStrategy: auditstrategy.Strategy, UpdateStrategy: auditstrategy.Strategy, DeleteStrategy: auditstrategy.Strategy, + + // TODO: define table converter that exposes more than name/creation timestamp + TableConvertor: rest.NewDefaultTableConvertor(auditregistration.Resource("auditsinks")), } options := &generic.StoreOptions{RESTOptions: optsGetter} if err := store.CompleteWithOptions(options); err != nil { diff --git a/pkg/registry/core/limitrange/storage/storage.go b/pkg/registry/core/limitrange/storage/storage.go index dac160ea96a..95af1d4fd1d 100644 --- a/pkg/registry/core/limitrange/storage/storage.go +++ b/pkg/registry/core/limitrange/storage/storage.go @@ -41,6 +41,9 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { UpdateStrategy: limitrange.Strategy, DeleteStrategy: limitrange.Strategy, ExportStrategy: limitrange.Strategy, + + // TODO: define table converter that exposes more than name/creation timestamp + TableConvertor: rest.NewDefaultTableConvertor(api.Resource("limitranges")), } options := &generic.StoreOptions{RESTOptions: optsGetter} if err := store.CompleteWithOptions(options); err != nil { diff --git a/pkg/registry/rbac/clusterrole/storage/BUILD b/pkg/registry/rbac/clusterrole/storage/BUILD index 2bffd61ab87..19c19bedfc7 100644 --- a/pkg/registry/rbac/clusterrole/storage/BUILD +++ b/pkg/registry/rbac/clusterrole/storage/BUILD @@ -15,6 +15,7 @@ go_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", + "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", ], ) diff --git a/pkg/registry/rbac/clusterrole/storage/storage.go b/pkg/registry/rbac/clusterrole/storage/storage.go index 7a32c8d7b5e..59347f767a4 100644 --- a/pkg/registry/rbac/clusterrole/storage/storage.go +++ b/pkg/registry/rbac/clusterrole/storage/storage.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/apiserver/pkg/registry/rest" "k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/registry/rbac/clusterrole" ) @@ -39,6 +40,9 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { CreateStrategy: clusterrole.Strategy, UpdateStrategy: clusterrole.Strategy, DeleteStrategy: clusterrole.Strategy, + + // TODO: define table converter that exposes more than name/creation timestamp? + TableConvertor: rest.NewDefaultTableConvertor(rbac.Resource("clusterroles")), } options := &generic.StoreOptions{RESTOptions: optsGetter} if err := store.CompleteWithOptions(options); err != nil { diff --git a/pkg/registry/rbac/role/storage/BUILD b/pkg/registry/rbac/role/storage/BUILD index 3b2548d3991..51844b9d43f 100644 --- a/pkg/registry/rbac/role/storage/BUILD +++ b/pkg/registry/rbac/role/storage/BUILD @@ -15,6 +15,7 @@ go_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", + "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", ], ) diff --git a/pkg/registry/rbac/role/storage/storage.go b/pkg/registry/rbac/role/storage/storage.go index 1c94fb89f95..6e6700ede98 100644 --- a/pkg/registry/rbac/role/storage/storage.go +++ b/pkg/registry/rbac/role/storage/storage.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/apiserver/pkg/registry/rest" "k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/registry/rbac/role" ) @@ -39,6 +40,9 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { CreateStrategy: role.Strategy, UpdateStrategy: role.Strategy, DeleteStrategy: role.Strategy, + + // TODO: define table converter that exposes more than name/creation timestamp? + TableConvertor: rest.NewDefaultTableConvertor(rbac.Resource("roles")), } options := &generic.StoreOptions{RESTOptions: optsGetter} if err := store.CompleteWithOptions(options); err != nil { diff --git a/pkg/registry/settings/podpreset/storage/BUILD b/pkg/registry/settings/podpreset/storage/BUILD index eddc3e03bb0..c106c75cf4e 100644 --- a/pkg/registry/settings/podpreset/storage/BUILD +++ b/pkg/registry/settings/podpreset/storage/BUILD @@ -16,6 +16,7 @@ go_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", + "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", ], ) diff --git a/pkg/registry/settings/podpreset/storage/storage.go b/pkg/registry/settings/podpreset/storage/storage.go index c2a7224db43..9fdd46bda9f 100644 --- a/pkg/registry/settings/podpreset/storage/storage.go +++ b/pkg/registry/settings/podpreset/storage/storage.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/apiserver/pkg/registry/rest" settingsapi "k8s.io/kubernetes/pkg/apis/settings" "k8s.io/kubernetes/pkg/registry/settings/podpreset" ) @@ -39,6 +40,9 @@ func NewREST(optsGetter generic.RESTOptionsGetter) (*REST, error) { CreateStrategy: podpreset.Strategy, UpdateStrategy: podpreset.Strategy, DeleteStrategy: podpreset.Strategy, + + // TODO: define table converter that exposes more than name/creation timestamp + TableConvertor: rest.NewDefaultTableConvertor(settingsapi.Resource("podpresets")), } options := &generic.StoreOptions{RESTOptions: optsGetter} if err := store.CompleteWithOptions(options); err != nil { diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go index 0368678e120..2252421148a 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go @@ -50,6 +50,9 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST CreateStrategy: strategy, UpdateStrategy: strategy, DeleteStrategy: strategy, + + // TODO: define table converter that exposes more than name/creation timestamp + TableConvertor: rest.NewDefaultTableConvertor(apiextensions.Resource("customresourcedefinitions")), } options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs} if err := store.CompleteWithOptions(options); err != nil { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 37579820a4a..06e0b211897 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -381,7 +381,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag resourceKind = kind } - tableProvider, _ := storage.(rest.TableConvertor) + tableProvider, isTableProvider := storage.(rest.TableConvertor) + if isLister && !isTableProvider { + // All listers must implement TableProvider + return nil, fmt.Errorf("%q must implement TableConvertor", resource) + } var apiResource metav1.APIResource if utilfeature.DefaultFeatureGate.Enabled(features.StorageVersionHash) && diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go index 3993bd2366c..edd75bc2af6 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go @@ -1217,6 +1217,10 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error { return fmt.Errorf("store for %s must set both KeyRootFunc and KeyFunc or neither", e.DefaultQualifiedResource.String()) } + if e.TableConvertor == nil { + return fmt.Errorf("store for %s must set TableConvertor; rest.NewDefaultTableConvertor(e.DefaultQualifiedResource) can be used to output just name/creation time", e.DefaultQualifiedResource.String()) + } + var isNamespaced bool switch { case e.CreateStrategy != nil: @@ -1377,7 +1381,7 @@ func (e *Store) ConvertToTable(ctx context.Context, object runtime.Object, table if e.TableConvertor != nil { return e.TableConvertor.ConvertToTable(ctx, object, tableOptions) } - return rest.NewDefaultTableConvertor(e.qualifiedResourceFromContext(ctx)).ConvertToTable(ctx, object, tableOptions) + return rest.NewDefaultTableConvertor(e.DefaultQualifiedResource).ConvertToTable(ctx, object, tableOptions) } func (e *Store) StorageVersion() runtime.GroupVersioner { diff --git a/staging/src/k8s.io/apiserver/pkg/registry/rest/table.go b/staging/src/k8s.io/apiserver/pkg/registry/rest/table.go index 31a46c74333..d90ae70762b 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/rest/table.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/rest/table.go @@ -26,15 +26,17 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" ) type defaultTableConvertor struct { - qualifiedResource schema.GroupResource + defaultQualifiedResource schema.GroupResource } -// NewDefaultTableConvertor creates a default convertor for the provided resource. -func NewDefaultTableConvertor(resource schema.GroupResource) TableConvertor { - return defaultTableConvertor{qualifiedResource: resource} +// NewDefaultTableConvertor creates a default convertor; the provided resource is used for error messages +// if no resource info can be determined from the context passed to ConvertToTable. +func NewDefaultTableConvertor(defaultQualifiedResource schema.GroupResource) TableConvertor { + return defaultTableConvertor{defaultQualifiedResource: defaultQualifiedResource} } var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc() @@ -44,7 +46,11 @@ func (c defaultTableConvertor) ConvertToTable(ctx context.Context, object runtim fn := func(obj runtime.Object) error { m, err := meta.Accessor(obj) if err != nil { - return errNotAcceptable{resource: c.qualifiedResource} + resource := c.defaultQualifiedResource + if info, ok := genericapirequest.RequestInfoFrom(ctx); ok { + resource = schema.GroupResource{Group: info.APIGroup, Resource: info.Resource} + } + return errNotAcceptable{resource: resource} } table.Rows = append(table.Rows, metav1.TableRow{ Cells: []interface{}{m.GetName(), m.GetCreationTimestamp().Time.UTC().Format(time.RFC3339)}, diff --git a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go index dd3562391a1..7fefca5ce49 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go +++ b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go @@ -48,6 +48,9 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST CreateStrategy: strategy, UpdateStrategy: strategy, DeleteStrategy: strategy, + + // TODO: define table converter that exposes more than name/creation timestamp + TableConvertor: rest.NewDefaultTableConvertor(apiregistration.Resource("apiservices")), } options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: apiservice.GetAttrs} if err := store.CompleteWithOptions(options); err != nil { diff --git a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/BUILD b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/BUILD index 6a3dc34d848..c674b2d8cb4 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/BUILD +++ b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/BUILD @@ -20,6 +20,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/validation/field: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", + "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", "//staging/src/k8s.io/sample-apiserver/pkg/apis/wardle:go_default_library", diff --git a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/etcd.go b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/etcd.go index 34473c8cf20..4a28fadc5a4 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/etcd.go +++ b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer/etcd.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/apiserver/pkg/registry/rest" "k8s.io/sample-apiserver/pkg/apis/wardle" "k8s.io/sample-apiserver/pkg/registry" ) @@ -37,6 +38,9 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*reg CreateStrategy: strategy, UpdateStrategy: strategy, DeleteStrategy: strategy, + + // TODO: define table converter that exposes more than name/creation timestamp + TableConvertor: rest.NewDefaultTableConvertor(wardle.Resource("fischers")), } options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs} if err := store.CompleteWithOptions(options); err != nil { diff --git a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/BUILD b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/BUILD index 34493fd591b..f10e2be4b52 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/BUILD +++ b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/BUILD @@ -20,6 +20,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/validation/field: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", + "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", "//staging/src/k8s.io/sample-apiserver/pkg/apis/wardle:go_default_library", diff --git a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/etcd.go b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/etcd.go index 99cf4d2a5c1..271e63cd96a 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/etcd.go +++ b/staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder/etcd.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" + "k8s.io/apiserver/pkg/registry/rest" "k8s.io/sample-apiserver/pkg/apis/wardle" "k8s.io/sample-apiserver/pkg/registry" ) @@ -37,6 +38,9 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*reg CreateStrategy: strategy, UpdateStrategy: strategy, DeleteStrategy: strategy, + + // TODO: define table converter that exposes more than name/creation timestamp + TableConvertor: rest.NewDefaultTableConvertor(wardle.Resource("flunders")), } options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs} if err := store.CompleteWithOptions(options); err != nil {