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 }