k8s.io/apiserver@v0.31.1/pkg/registry/rest/rest.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package rest
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  	"net/http"
    23  	"net/url"
    24  
    25  	metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/runtime"
    28  	"k8s.io/apimachinery/pkg/runtime/schema"
    29  	"k8s.io/apimachinery/pkg/watch"
    30  	"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
    31  )
    32  
    33  //TODO:
    34  // Storage interfaces need to be separated into two groups; those that operate
    35  // on collections and those that operate on individually named items.
    36  // Collection interfaces:
    37  // (Method: Current -> Proposed)
    38  //    GET: Lister -> CollectionGetter
    39  //    WATCH: Watcher -> CollectionWatcher
    40  //    CREATE: Creater -> CollectionCreater
    41  //    DELETE: (n/a) -> CollectionDeleter
    42  //    UPDATE: (n/a) -> CollectionUpdater
    43  //
    44  // Single item interfaces:
    45  // (Method: Current -> Proposed)
    46  //    GET: Getter -> NamedGetter
    47  //    WATCH: (n/a) -> NamedWatcher
    48  //    CREATE: (n/a) -> NamedCreater
    49  //    DELETE: Deleter -> NamedDeleter
    50  //    UPDATE: Update -> NamedUpdater
    51  
    52  // Storage is a generic interface for RESTful storage services.
    53  // Resources which are exported to the RESTful API of apiserver need to implement this interface. It is expected
    54  // that objects may implement any of the below interfaces.
    55  //
    56  // Consider using StorageWithReadiness whenever possible.
    57  type Storage interface {
    58  	// New returns an empty object that can be used with Create and Update after request data has been put into it.
    59  	// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
    60  	New() runtime.Object
    61  
    62  	// Destroy cleans up its resources on shutdown.
    63  	// Destroy has to be implemented in thread-safe way and be prepared
    64  	// for being called more than once.
    65  	Destroy()
    66  }
    67  
    68  // StorageWithReadiness extends Storage interface with the readiness check.
    69  type StorageWithReadiness interface {
    70  	Storage
    71  
    72  	// ReadinessCheck allows for checking storage readiness.
    73  	ReadinessCheck() error
    74  }
    75  
    76  // Scoper indicates what scope the resource is at. It must be specified.
    77  // It is usually provided automatically based on your strategy.
    78  type Scoper interface {
    79  	// NamespaceScoped returns true if the storage is namespaced
    80  	NamespaceScoped() bool
    81  }
    82  
    83  // KindProvider specifies a different kind for its API than for its internal storage.  This is necessary for external
    84  // objects that are not compiled into the api server.  For such objects, there is no in-memory representation for
    85  // the object, so they must be represented as generic objects (e.g. runtime.Unknown), but when we present the object as part of
    86  // API discovery we want to present the specific kind, not the generic internal representation.
    87  type KindProvider interface {
    88  	Kind() string
    89  }
    90  
    91  // ShortNamesProvider is an interface for RESTful storage services. Delivers a list of short names for a resource. The list is used by kubectl to have short names representation of resources.
    92  type ShortNamesProvider interface {
    93  	ShortNames() []string
    94  }
    95  
    96  // CategoriesProvider allows a resource to specify which groups of resources (categories) it's part of. Categories can
    97  // be used by API clients to refer to a batch of resources by using a single name (e.g. "all" could translate to "pod,rc,svc,...").
    98  type CategoriesProvider interface {
    99  	Categories() []string
   100  }
   101  
   102  // SingularNameProvider returns singular name of resources. This is used by kubectl discovery to have singular
   103  // name representation of resources. In case of shortcut conflicts(with CRD shortcuts) singular name should always map to this resource.
   104  type SingularNameProvider interface {
   105  	GetSingularName() string
   106  }
   107  
   108  // GroupVersionKindProvider is used to specify a particular GroupVersionKind to discovery.  This is used for polymorphic endpoints
   109  // which generally point to foreign versions.  Scale refers to Scale.v1beta1.extensions for instance.
   110  // This trumps KindProvider since it is capable of providing the information required.
   111  // TODO KindProvider (only used by federation) should be removed and replaced with this, but that presents greater risk late in 1.8.
   112  type GroupVersionKindProvider interface {
   113  	GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind
   114  }
   115  
   116  // GroupVersionAcceptor is used to determine if a particular GroupVersion is acceptable to send to an endpoint.
   117  // This is used for endpoints which accept multiple versions (which is extremely rare).
   118  // The only known instance is pods/evictions which accepts policy/v1, but also policy/v1beta1 for backwards compatibility.
   119  type GroupVersionAcceptor interface {
   120  	AcceptsGroupVersion(gv schema.GroupVersion) bool
   121  }
   122  
   123  // Lister is an object that can retrieve resources that match the provided field and label criteria.
   124  type Lister interface {
   125  	// NewList returns an empty object that can be used with the List call.
   126  	// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
   127  	NewList() runtime.Object
   128  	// List selects resources in the storage which match to the selector. 'options' can be nil.
   129  	List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error)
   130  	// TableConvertor ensures all list implementers also implement table conversion
   131  	TableConvertor
   132  }
   133  
   134  // Getter is an object that can retrieve a named RESTful resource.
   135  type Getter interface {
   136  	// Get finds a resource in the storage by name and returns it.
   137  	// Although it can return an arbitrary error value, IsNotFound(err) is true for the
   138  	// returned error value err when the specified resource is not found.
   139  	Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error)
   140  }
   141  
   142  // GetterWithOptions is an object that retrieve a named RESTful resource and takes
   143  // additional options on the get request. It allows a caller to also receive the
   144  // subpath of the GET request.
   145  type GetterWithOptions interface {
   146  	// Get finds a resource in the storage by name and returns it.
   147  	// Although it can return an arbitrary error value, IsNotFound(err) is true for the
   148  	// returned error value err when the specified resource is not found.
   149  	// The options object passed to it is of the same type returned by the NewGetOptions
   150  	// method.
   151  	// TODO: Pass metav1.GetOptions.
   152  	Get(ctx context.Context, name string, options runtime.Object) (runtime.Object, error)
   153  
   154  	// NewGetOptions returns an empty options object that will be used to pass
   155  	// options to the Get method. It may return a bool and a string, if true, the
   156  	// value of the request path below the object will be included as the named
   157  	// string in the serialization of the runtime object. E.g., returning "path"
   158  	// will convert the trailing request scheme value to "path" in the map[string][]string
   159  	// passed to the converter.
   160  	NewGetOptions() (runtime.Object, bool, string)
   161  }
   162  
   163  type TableConvertor interface {
   164  	ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error)
   165  }
   166  
   167  // GracefulDeleter knows how to pass deletion options to allow delayed deletion of a
   168  // RESTful object.
   169  type GracefulDeleter interface {
   170  	// Delete finds a resource in the storage and deletes it.
   171  	// The delete attempt is validated by the deleteValidation first.
   172  	// If options are provided, the resource will attempt to honor them or return an invalid
   173  	// request error.
   174  	// Although it can return an arbitrary error value, IsNotFound(err) is true for the
   175  	// returned error value err when the specified resource is not found.
   176  	// Delete *may* return the object that was deleted, or a status object indicating additional
   177  	// information about deletion.
   178  	// It also returns a boolean which is set to true if the resource was instantly
   179  	// deleted or false if it will be deleted asynchronously.
   180  	Delete(ctx context.Context, name string, deleteValidation ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error)
   181  }
   182  
   183  // MayReturnFullObjectDeleter may return deleted object (instead of a simple status) on deletion.
   184  type MayReturnFullObjectDeleter interface {
   185  	DeleteReturnsDeletedObject() bool
   186  }
   187  
   188  // CollectionDeleter is an object that can delete a collection
   189  // of RESTful resources.
   190  type CollectionDeleter interface {
   191  	// DeleteCollection selects all resources in the storage matching given 'listOptions'
   192  	// and deletes them. The delete attempt is validated by the deleteValidation first.
   193  	// If 'options' are provided, the resource will attempt to honor them or return an
   194  	// invalid request error.
   195  	// DeleteCollection may not be atomic - i.e. it may delete some objects and still
   196  	// return an error after it. On success, returns a list of deleted objects.
   197  	DeleteCollection(ctx context.Context, deleteValidation ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error)
   198  }
   199  
   200  // Creater is an object that can create an instance of a RESTful object.
   201  type Creater interface {
   202  	// New returns an empty object that can be used with Create after request data has been put into it.
   203  	// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
   204  	New() runtime.Object
   205  
   206  	// Create creates a new version of a resource.
   207  	Create(ctx context.Context, obj runtime.Object, createValidation ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error)
   208  }
   209  
   210  // NamedCreater is an object that can create an instance of a RESTful object using a name parameter.
   211  type NamedCreater interface {
   212  	// New returns an empty object that can be used with Create after request data has been put into it.
   213  	// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
   214  	New() runtime.Object
   215  
   216  	// Create creates a new version of a resource. It expects a name parameter from the path.
   217  	// This is needed for create operations on subresources which include the name of the parent
   218  	// resource in the path.
   219  	Create(ctx context.Context, name string, obj runtime.Object, createValidation ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error)
   220  }
   221  
   222  // SubresourceObjectMetaPreserver adds configuration options to a Creater for subresources.
   223  type SubresourceObjectMetaPreserver interface {
   224  	// PreserveRequestObjectMetaSystemFieldsOnSubresourceCreate indicates that a
   225  	// handler should preserve fields of ObjectMeta that are managed by the system.
   226  	PreserveRequestObjectMetaSystemFieldsOnSubresourceCreate() bool
   227  }
   228  
   229  // UpdatedObjectInfo provides information about an updated object to an Updater.
   230  // It requires access to the old object in order to return the newly updated object.
   231  type UpdatedObjectInfo interface {
   232  	// Returns preconditions built from the updated object, if applicable.
   233  	// May return nil, or a preconditions object containing nil fields,
   234  	// if no preconditions can be determined from the updated object.
   235  	Preconditions() *metav1.Preconditions
   236  
   237  	// UpdatedObject returns the updated object, given a context and old object.
   238  	// The only time an empty oldObj should be passed in is if a "create on update" is occurring (there is no oldObj).
   239  	UpdatedObject(ctx context.Context, oldObj runtime.Object) (newObj runtime.Object, err error)
   240  }
   241  
   242  // ValidateObjectFunc is a function to act on a given object. An error may be returned
   243  // if the hook cannot be completed. A ValidateObjectFunc may NOT transform the provided
   244  // object.
   245  type ValidateObjectFunc func(ctx context.Context, obj runtime.Object) error
   246  
   247  // ValidateAllObjectFunc is a "admit everything" instance of ValidateObjectFunc.
   248  func ValidateAllObjectFunc(ctx context.Context, obj runtime.Object) error {
   249  	return nil
   250  }
   251  
   252  // ValidateObjectUpdateFunc is a function to act on a given object and its predecessor.
   253  // An error may be returned if the hook cannot be completed. An UpdateObjectFunc
   254  // may NOT transform the provided object.
   255  type ValidateObjectUpdateFunc func(ctx context.Context, obj, old runtime.Object) error
   256  
   257  // ValidateAllObjectUpdateFunc is a "admit everything" instance of ValidateObjectUpdateFunc.
   258  func ValidateAllObjectUpdateFunc(ctx context.Context, obj, old runtime.Object) error {
   259  	return nil
   260  }
   261  
   262  // Updater is an object that can update an instance of a RESTful object.
   263  type Updater interface {
   264  	// New returns an empty object that can be used with Update after request data has been put into it.
   265  	// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
   266  	New() runtime.Object
   267  
   268  	// Update finds a resource in the storage and updates it. Some implementations
   269  	// may allow updates creates the object - they should set the created boolean
   270  	// to true.
   271  	Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error)
   272  }
   273  
   274  // CreaterUpdater is a storage object that must support both create and update.
   275  // Go prevents embedded interfaces that implement the same method.
   276  type CreaterUpdater interface {
   277  	Creater
   278  	Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error)
   279  }
   280  
   281  // CreaterUpdater must satisfy the Updater interface.
   282  var _ Updater = CreaterUpdater(nil)
   283  
   284  // Patcher is a storage object that supports both get and update.
   285  type Patcher interface {
   286  	Getter
   287  	Updater
   288  }
   289  
   290  // Watcher should be implemented by all Storage objects that
   291  // want to offer the ability to watch for changes through the watch api.
   292  type Watcher interface {
   293  	// 'label' selects on labels; 'field' selects on the object's fields. Not all fields
   294  	// are supported; an error should be returned if 'field' tries to select on a field that
   295  	// isn't supported. 'resourceVersion' allows for continuing/starting a watch at a
   296  	// particular version.
   297  	Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error)
   298  }
   299  
   300  // StandardStorage is an interface covering the common verbs. Provided for testing whether a
   301  // resource satisfies the normal storage methods. Use Storage when passing opaque storage objects.
   302  type StandardStorage interface {
   303  	Getter
   304  	Lister
   305  	CreaterUpdater
   306  	GracefulDeleter
   307  	CollectionDeleter
   308  	Watcher
   309  
   310  	// Destroy cleans up its resources on shutdown.
   311  	// Destroy has to be implemented in thread-safe way and be prepared
   312  	// for being called more than once.
   313  	Destroy()
   314  }
   315  
   316  // Redirector know how to return a remote resource's location.
   317  type Redirector interface {
   318  	// ResourceLocation should return the remote location of the given resource, and an optional transport to use to request it, or an error.
   319  	ResourceLocation(ctx context.Context, id string) (remoteLocation *url.URL, transport http.RoundTripper, err error)
   320  }
   321  
   322  // Responder abstracts the normal response behavior for a REST method and is passed to callers that
   323  // may wish to handle the response directly in some cases, but delegate to the normal error or object
   324  // behavior in other cases.
   325  type Responder interface {
   326  	// Object writes the provided object to the response. Invoking this method multiple times is undefined.
   327  	Object(statusCode int, obj runtime.Object)
   328  	// Error writes the provided error to the response. This method may only be invoked once.
   329  	Error(err error)
   330  }
   331  
   332  // Connecter is a storage object that responds to a connection request.
   333  type Connecter interface {
   334  	// Connect returns an http.Handler that will handle the request/response for a given API invocation.
   335  	// The provided responder may be used for common API responses. The responder will write both status
   336  	// code and body, so the ServeHTTP method should exit after invoking the responder. The Handler will
   337  	// be used for a single API request and then discarded. The Responder is guaranteed to write to the
   338  	// same http.ResponseWriter passed to ServeHTTP.
   339  	Connect(ctx context.Context, id string, options runtime.Object, r Responder) (http.Handler, error)
   340  
   341  	// NewConnectOptions returns an empty options object that will be used to pass
   342  	// options to the Connect method. If nil, then a nil options object is passed to
   343  	// Connect. It may return a bool and a string. If true, the value of the request
   344  	// path below the object will be included as the named string in the serialization
   345  	// of the runtime object.
   346  	NewConnectOptions() (runtime.Object, bool, string)
   347  
   348  	// ConnectMethods returns the list of HTTP methods handled by Connect
   349  	ConnectMethods() []string
   350  }
   351  
   352  // ResourceStreamer is an interface implemented by objects that prefer to be streamed from the server
   353  // instead of decoded directly.
   354  type ResourceStreamer interface {
   355  	// InputStream should return an io.ReadCloser if the provided object supports streaming. The desired
   356  	// api version and an accept header (may be empty) are passed to the call. If no error occurs,
   357  	// the caller may return a flag indicating whether the result should be flushed as writes occur
   358  	// and a content type string that indicates the type of the stream.
   359  	// If a null stream is returned, a StatusNoContent response wil be generated.
   360  	InputStream(ctx context.Context, apiVersion, acceptHeader string) (stream io.ReadCloser, flush bool, mimeType string, err error)
   361  }
   362  
   363  // StorageMetadata is an optional interface that callers can implement to provide additional
   364  // information about their Storage objects.
   365  type StorageMetadata interface {
   366  	// ProducesMIMETypes returns a list of the MIME types the specified HTTP verb (GET, POST, DELETE,
   367  	// PATCH) can respond with.
   368  	ProducesMIMETypes(verb string) []string
   369  
   370  	// ProducesObject returns an object the specified HTTP verb respond with. It will overwrite storage object if
   371  	// it is not nil. Only the type of the return object matters, the value will be ignored.
   372  	ProducesObject(verb string) interface{}
   373  }
   374  
   375  // StorageVersionProvider is an optional interface that a storage object can
   376  // implement if it wishes to disclose its storage version.
   377  type StorageVersionProvider interface {
   378  	// StorageVersion returns a group versioner, which will outputs the gvk
   379  	// an object will be converted to before persisted in etcd, given a
   380  	// list of kinds the object might belong to.
   381  	StorageVersion() runtime.GroupVersioner
   382  }
   383  
   384  // ResetFieldsStrategy is an optional interface that a storage object can
   385  // implement if it wishes to provide the fields reset by its strategies.
   386  type ResetFieldsStrategy interface {
   387  	GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set
   388  }
   389  
   390  // CreateUpdateResetFieldsStrategy is a union of RESTCreateUpdateStrategy
   391  // and ResetFieldsStrategy.
   392  type CreateUpdateResetFieldsStrategy interface {
   393  	RESTCreateUpdateStrategy
   394  	ResetFieldsStrategy
   395  }
   396  
   397  // UpdateResetFieldsStrategy is a union of RESTUpdateStrategy
   398  // and ResetFieldsStrategy.
   399  type UpdateResetFieldsStrategy interface {
   400  	RESTUpdateStrategy
   401  	ResetFieldsStrategy
   402  }