mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Switch genericapiserver to use metainternalversion.ListOptions
Decouple ListOption parsing from the scheme - instead, it is a property of the server (and clients should use metav1.ListOptions for now).
This commit is contained in:
parent
c12344b3b8
commit
3ba366fcf1
@ -36,6 +36,7 @@ import (
|
||||
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -117,20 +118,11 @@ func newMapper() *meta.DefaultRESTMapper {
|
||||
}
|
||||
|
||||
func addGrouplessTypes() {
|
||||
type ListOptions struct {
|
||||
Object runtime.Object
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
LabelSelector string `json:"labelSelector,omitempty"`
|
||||
FieldSelector string `json:"fieldSelector,omitempty"`
|
||||
Watch bool `json:"watch,omitempty"`
|
||||
ResourceVersion string `json:"resourceVersion,omitempty"`
|
||||
TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty"`
|
||||
}
|
||||
api.Scheme.AddKnownTypes(grouplessGroupVersion,
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &ListOptions{}, &metav1.ExportOptions{},
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ListOptions{}, &metav1.ExportOptions{},
|
||||
&v1.DeleteOptions{}, &genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{})
|
||||
api.Scheme.AddKnownTypes(grouplessInternalGroupVersion,
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &api.ListOptions{}, &metav1.ExportOptions{},
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{},
|
||||
&genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{})
|
||||
}
|
||||
|
||||
@ -145,12 +137,12 @@ func addTestTypes() {
|
||||
TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty"`
|
||||
}
|
||||
api.Scheme.AddKnownTypes(testGroupVersion,
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &ListOptions{}, &metav1.ExportOptions{},
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{},
|
||||
&v1.DeleteOptions{}, &genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{},
|
||||
&SimpleXGSubresource{})
|
||||
api.Scheme.AddKnownTypes(testGroupVersion, &v1.Pod{})
|
||||
api.Scheme.AddKnownTypes(testInternalGroupVersion,
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &api.ListOptions{}, &metav1.ExportOptions{},
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{},
|
||||
&genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{},
|
||||
&SimpleXGSubresource{})
|
||||
api.Scheme.AddKnownTypes(testInternalGroupVersion, &api.Pod{})
|
||||
@ -163,17 +155,8 @@ func addTestTypes() {
|
||||
}
|
||||
|
||||
func addNewTestTypes() {
|
||||
type ListOptions struct {
|
||||
Object runtime.Object
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
LabelSelector string `json:"labelSelector,omitempty"`
|
||||
FieldSelector string `json:"fieldSelector,omitempty"`
|
||||
Watch bool `json:"watch,omitempty"`
|
||||
ResourceVersion string `json:"resourceVersion,omitempty"`
|
||||
TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty"`
|
||||
}
|
||||
api.Scheme.AddKnownTypes(newGroupVersion,
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &ListOptions{}, &metav1.ExportOptions{},
|
||||
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{},
|
||||
&api.DeleteOptions{}, &genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{},
|
||||
&v1.Pod{},
|
||||
)
|
||||
@ -393,7 +376,7 @@ func (storage *SimpleRESTStorage) Export(ctx request.Context, name string, opts
|
||||
return obj, storage.errors["export"]
|
||||
}
|
||||
|
||||
func (storage *SimpleRESTStorage) List(ctx request.Context, options *api.ListOptions) (runtime.Object, error) {
|
||||
func (storage *SimpleRESTStorage) List(ctx request.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
storage.checkContext(ctx)
|
||||
result := &genericapitesting.SimpleList{
|
||||
Items: storage.list,
|
||||
@ -509,7 +492,7 @@ func (storage *SimpleRESTStorage) Update(ctx request.Context, name string, objIn
|
||||
}
|
||||
|
||||
// Implement ResourceWatcher.
|
||||
func (storage *SimpleRESTStorage) Watch(ctx request.Context, options *api.ListOptions) (watch.Interface, error) {
|
||||
func (storage *SimpleRESTStorage) Watch(ctx request.Context, options *metainternalversion.ListOptions) (watch.Interface, error) {
|
||||
storage.lock.Lock()
|
||||
defer storage.lock.Unlock()
|
||||
storage.checkContext(ctx)
|
||||
|
@ -53,6 +53,10 @@ type APIGroupVersion struct {
|
||||
// define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. If
|
||||
// empty, defaults to GroupVersion.
|
||||
OptionsExternalVersion *schema.GroupVersion
|
||||
// MetaGroupVersion defaults to "meta.k8s.io/v1" and is the scheme group version used to decode
|
||||
// common API implementations like ListOptions. Future changes will allow this to vary by group
|
||||
// version (for when the inevitable meta/v2 group emerges).
|
||||
MetaGroupVersion *schema.GroupVersion
|
||||
|
||||
Mapper meta.RESTMapper
|
||||
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@ -87,6 +88,8 @@ type RequestScope struct {
|
||||
Resource schema.GroupVersionResource
|
||||
Kind schema.GroupVersionKind
|
||||
Subresource string
|
||||
|
||||
MetaGroupVersion schema.GroupVersion
|
||||
}
|
||||
|
||||
func (scope *RequestScope) err(err error, w http.ResponseWriter, req *http.Request) {
|
||||
@ -264,8 +267,8 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope RequestScope, forceWatch
|
||||
ctx := scope.ContextFunc(req)
|
||||
ctx = request.WithNamespace(ctx, namespace)
|
||||
|
||||
opts := api.ListOptions{}
|
||||
if err := scope.ParameterCodec.DecodeParameters(req.Request.URL.Query(), scope.Kind.GroupVersion(), &opts); err != nil {
|
||||
opts := metainternalversion.ListOptions{}
|
||||
if err := metainternalversion.ParameterCodec.DecodeParameters(req.Request.URL.Query(), scope.MetaGroupVersion, &opts); err != nil {
|
||||
scope.err(err, res.ResponseWriter, req.Request)
|
||||
return
|
||||
}
|
||||
@ -912,8 +915,8 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
||||
}
|
||||
}
|
||||
|
||||
listOptions := api.ListOptions{}
|
||||
if err := scope.ParameterCodec.DecodeParameters(req.Request.URL.Query(), scope.Kind.GroupVersion(), &listOptions); err != nil {
|
||||
listOptions := metainternalversion.ListOptions{}
|
||||
if err := metainternalversion.ParameterCodec.DecodeParameters(req.Request.URL.Query(), scope.MetaGroupVersion, &listOptions); err != nil {
|
||||
scope.err(err, res.ResponseWriter, req.Request)
|
||||
return
|
||||
}
|
||||
|
@ -521,6 +521,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
||||
Resource: a.group.GroupVersion.WithResource(resource),
|
||||
Subresource: subresource,
|
||||
Kind: fqKindToRegister,
|
||||
|
||||
MetaGroupVersion: metav1.SchemeGroupVersion,
|
||||
}
|
||||
if a.group.MetaGroupVersion != nil {
|
||||
reqScope.MetaGroupVersion = *a.group.MetaGroupVersion
|
||||
}
|
||||
for _, action := range actions {
|
||||
versionedObject := storageMeta.ProducesObject(action.Verb)
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
|
||||
kubeerr "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -221,7 +222,7 @@ func (e *Store) NewList() runtime.Object {
|
||||
|
||||
// List returns a list of items matching labels and field according to the
|
||||
// store's PredicateFunc.
|
||||
func (e *Store) List(ctx genericapirequest.Context, options *api.ListOptions) (runtime.Object, error) {
|
||||
func (e *Store) List(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
label := labels.Everything()
|
||||
if options != nil && options.LabelSelector != nil {
|
||||
label = options.LabelSelector
|
||||
@ -244,10 +245,10 @@ func (e *Store) List(ctx genericapirequest.Context, options *api.ListOptions) (r
|
||||
|
||||
// ListPredicate returns a list of all the items matching the given
|
||||
// SelectionPredicate.
|
||||
func (e *Store) ListPredicate(ctx genericapirequest.Context, p storage.SelectionPredicate, options *api.ListOptions) (runtime.Object, error) {
|
||||
func (e *Store) ListPredicate(ctx genericapirequest.Context, p storage.SelectionPredicate, options *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
if options == nil {
|
||||
// By default we should serve the request from etcd.
|
||||
options = &api.ListOptions{ResourceVersion: ""}
|
||||
options = &metainternalversion.ListOptions{ResourceVersion: ""}
|
||||
}
|
||||
list := e.NewListFunc()
|
||||
if name, ok := p.MatchesSingle(); ok {
|
||||
@ -830,7 +831,7 @@ func (e *Store) Delete(ctx genericapirequest.Context, name string, options *api.
|
||||
// are removing all objects of a given type) with the current API (it's technically
|
||||
// possibly with storage API, but watch is not delivered correctly then).
|
||||
// It will be possible to fix it with v3 etcd API.
|
||||
func (e *Store) DeleteCollection(ctx genericapirequest.Context, options *api.DeleteOptions, listOptions *api.ListOptions) (runtime.Object, error) {
|
||||
func (e *Store) DeleteCollection(ctx genericapirequest.Context, options *api.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
listObj, err := e.List(ctx, listOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -921,7 +922,7 @@ func (e *Store) finalizeDelete(obj runtime.Object, runHooks bool) (runtime.Objec
|
||||
// WatchPredicate. If possible, you should customize PredicateFunc to produce
|
||||
// a matcher that matches by key. SelectionPredicate does this for you
|
||||
// automatically.
|
||||
func (e *Store) Watch(ctx genericapirequest.Context, options *api.ListOptions) (watch.Interface, error) {
|
||||
func (e *Store) Watch(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (watch.Interface, error) {
|
||||
label := labels.Everything()
|
||||
if options != nil && options.LabelSelector != nil {
|
||||
label = options.LabelSelector
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@ -239,7 +240,7 @@ func TestStoreListResourceVersion(t *testing.T) {
|
||||
|
||||
waitListCh := make(chan runtime.Object, 1)
|
||||
go func(listRev uint64) {
|
||||
option := &api.ListOptions{ResourceVersion: strconv.FormatUint(listRev, 10)}
|
||||
option := &metainternalversion.ListOptions{ResourceVersion: strconv.FormatUint(listRev, 10)}
|
||||
// It will wait until we create the second pod.
|
||||
l, err := registry.List(ctx, option)
|
||||
if err != nil {
|
||||
@ -1078,7 +1079,7 @@ func TestStoreDeleteCollection(t *testing.T) {
|
||||
}
|
||||
|
||||
// Delete all pods.
|
||||
deleted, err := registry.DeleteCollection(testContext, nil, &api.ListOptions{})
|
||||
deleted, err := registry.DeleteCollection(testContext, nil, &metainternalversion.ListOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -1119,7 +1120,7 @@ func TestStoreDeleteCollectionNotFound(t *testing.T) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
_, err := registry.DeleteCollection(testContext, nil, &api.ListOptions{})
|
||||
_, err := registry.DeleteCollection(testContext, nil, &metainternalversion.ListOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -1157,7 +1158,7 @@ func TestStoreDeleteCollectionWithWatch(t *testing.T) {
|
||||
}
|
||||
defer watcher.Stop()
|
||||
|
||||
if _, err := registry.DeleteCollection(testContext, nil, &api.ListOptions{}); err != nil {
|
||||
if _, err := registry.DeleteCollection(testContext, nil, &metainternalversion.ListOptions{}); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -71,7 +72,7 @@ type Lister interface {
|
||||
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
|
||||
NewList() runtime.Object
|
||||
// List selects resources in the storage which match to the selector. 'options' can be nil.
|
||||
List(ctx genericapirequest.Context, options *api.ListOptions) (runtime.Object, error)
|
||||
List(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// Exporter is an object that knows how to strip a RESTful resource for export
|
||||
@ -152,7 +153,7 @@ type CollectionDeleter interface {
|
||||
// them or return an invalid request error.
|
||||
// DeleteCollection may not be atomic - i.e. it may delete some objects and still
|
||||
// return an error after it. On success, returns a list of deleted objects.
|
||||
DeleteCollection(ctx genericapirequest.Context, options *api.DeleteOptions, listOptions *api.ListOptions) (runtime.Object, error)
|
||||
DeleteCollection(ctx genericapirequest.Context, options *api.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// Creater is an object that can create an instance of a RESTful object.
|
||||
@ -225,7 +226,7 @@ type Watcher interface {
|
||||
// are supported; an error should be returned if 'field' tries to select on a field that
|
||||
// isn't supported. 'resourceVersion' allows for continuing/starting a watch at a
|
||||
// particular version.
|
||||
Watch(ctx genericapirequest.Context, options *api.ListOptions) (watch.Interface, error)
|
||||
Watch(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
// StandardStorage is an interface covering the common verbs. Provided for testing whether a
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
@ -1196,7 +1197,7 @@ func (t *Tester) testListMatchLabels(obj runtime.Object, assignFn AssignFunc) {
|
||||
filtered := []runtime.Object{objs[1]}
|
||||
|
||||
selector := labels.SelectorFromSet(labels.Set(testLabels))
|
||||
options := &api.ListOptions{LabelSelector: selector}
|
||||
options := &metainternalversion.ListOptions{LabelSelector: selector}
|
||||
listObj, err := t.storage.(rest.Lister).List(ctx, options)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
@ -1238,7 +1239,7 @@ func (t *Tester) testWatchFields(obj runtime.Object, emitFn EmitFunc, fieldsPass
|
||||
|
||||
for _, field := range fieldsPass {
|
||||
for _, action := range actions {
|
||||
options := &api.ListOptions{FieldSelector: field.AsSelector(), ResourceVersion: "1"}
|
||||
options := &metainternalversion.ListOptions{FieldSelector: field.AsSelector(), ResourceVersion: "1"}
|
||||
watcher, err := t.storage.(rest.Watcher).Watch(ctx, options)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v, %v", err, action)
|
||||
@ -1262,7 +1263,7 @@ func (t *Tester) testWatchFields(obj runtime.Object, emitFn EmitFunc, fieldsPass
|
||||
|
||||
for _, field := range fieldsFail {
|
||||
for _, action := range actions {
|
||||
options := &api.ListOptions{FieldSelector: field.AsSelector(), ResourceVersion: "1"}
|
||||
options := &metainternalversion.ListOptions{FieldSelector: field.AsSelector(), ResourceVersion: "1"}
|
||||
watcher, err := t.storage.(rest.Watcher).Watch(ctx, options)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
@ -1287,7 +1288,7 @@ func (t *Tester) testWatchLabels(obj runtime.Object, emitFn EmitFunc, labelsPass
|
||||
|
||||
for _, label := range labelsPass {
|
||||
for _, action := range actions {
|
||||
options := &api.ListOptions{LabelSelector: label.AsSelector(), ResourceVersion: "1"}
|
||||
options := &metainternalversion.ListOptions{LabelSelector: label.AsSelector(), ResourceVersion: "1"}
|
||||
watcher, err := t.storage.(rest.Watcher).Watch(ctx, options)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
@ -1310,7 +1311,7 @@ func (t *Tester) testWatchLabels(obj runtime.Object, emitFn EmitFunc, labelsPass
|
||||
|
||||
for _, label := range labelsFail {
|
||||
for _, action := range actions {
|
||||
options := &api.ListOptions{LabelSelector: label.AsSelector(), ResourceVersion: "1"}
|
||||
options := &metainternalversion.ListOptions{LabelSelector: label.AsSelector(), ResourceVersion: "1"}
|
||||
watcher, err := t.storage.(rest.Watcher).Watch(ctx, options)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
|
@ -59,6 +59,10 @@ type APIGroupInfo struct {
|
||||
// If nil, defaults to groupMeta.GroupVersion.
|
||||
// TODO: Remove this when https://github.com/kubernetes/kubernetes/issues/19018 is fixed.
|
||||
OptionsExternalVersion *schema.GroupVersion
|
||||
// MetaGroupVersion defaults to "meta.k8s.io/v1" and is the scheme group version used to decode
|
||||
// common API implementations like ListOptions. Future changes will allow this to vary by group
|
||||
// version (for when the inevitable meta/v2 group emerges).
|
||||
MetaGroupVersion *schema.GroupVersion
|
||||
|
||||
// Scheme includes all of the types used by this group and how to convert between them (or
|
||||
// to convert objects from outside of this group that are accepted in this API).
|
||||
@ -322,7 +326,8 @@ func (s *GenericAPIServer) getAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
|
||||
|
||||
func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupVersion schema.GroupVersion) *genericapi.APIGroupVersion {
|
||||
return &genericapi.APIGroupVersion{
|
||||
GroupVersion: groupVersion,
|
||||
GroupVersion: groupVersion,
|
||||
MetaGroupVersion: apiGroupInfo.MetaGroupVersion,
|
||||
|
||||
ParameterCodec: apiGroupInfo.ParameterCodec,
|
||||
Serializer: apiGroupInfo.NegotiatedSerializer,
|
||||
|
Loading…
Reference in New Issue
Block a user