blob: d84146fecf5f6b0e14236ef2d83fee5f1fc88ec8 [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001/*
2Copyright 2014 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package rest
18
19import (
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 metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
28 "k8s.io/apimachinery/pkg/runtime"
29 "k8s.io/apimachinery/pkg/runtime/schema"
30 "k8s.io/apimachinery/pkg/watch"
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.
55type Storage interface {
56 // New returns an empty object that can be used with Create and Update after request data has been put into it.
57 // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
58 New() runtime.Object
59}
60
61// Scoper indicates what scope the resource is at. It must be specified.
62// It is usually provided automatically based on your strategy.
63type Scoper interface {
64 // NamespaceScoped returns true if the storage is namespaced
65 NamespaceScoped() bool
66}
67
68// KindProvider specifies a different kind for its API than for its internal storage. This is necessary for external
69// objects that are not compiled into the api server. For such objects, there is no in-memory representation for
70// the object, so they must be represented as generic objects (e.g. runtime.Unknown), but when we present the object as part of
71// API discovery we want to present the specific kind, not the generic internal representation.
72type KindProvider interface {
73 Kind() string
74}
75
76// 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.
77type ShortNamesProvider interface {
78 ShortNames() []string
79}
80
81// CategoriesProvider allows a resource to specify which groups of resources (categories) it's part of. Categories can
82// 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,...").
83type CategoriesProvider interface {
84 Categories() []string
85}
86
87// GroupVersionKindProvider is used to specify a particular GroupVersionKind to discovery. This is used for polymorphic endpoints
88// which generally point to foreign versions. Scale refers to Scale.v1beta1.extensions for instance.
89// This trumps KindProvider since it is capable of providing the information required.
90// TODO KindProvider (only used by federation) should be removed and replaced with this, but that presents greater risk late in 1.8.
91type GroupVersionKindProvider interface {
92 GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind
93}
94
95// Lister is an object that can retrieve resources that match the provided field and label criteria.
96type Lister interface {
97 // NewList returns an empty object that can be used with the List call.
98 // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
99 NewList() runtime.Object
100 // List selects resources in the storage which match to the selector. 'options' can be nil.
101 List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error)
102}
103
104// Exporter is an object that knows how to strip a RESTful resource for export. A store should implement this interface
105// if export is generally supported for that type. Errors can still be returned during the actual Export when certain
106// instances of the type are not exportable.
107type Exporter interface {
108 // Export an object. Fields that are not user specified (e.g. Status, ObjectMeta.ResourceVersion) are stripped out
109 // Returns the stripped object. If 'exact' is true, fields that are specific to the cluster (e.g. namespace) are
110 // retained, otherwise they are stripped also.
111 Export(ctx context.Context, name string, opts metav1.ExportOptions) (runtime.Object, error)
112}
113
114// Getter is an object that can retrieve a named RESTful resource.
115type Getter interface {
116 // Get finds a resource in the storage by name and returns it.
117 // Although it can return an arbitrary error value, IsNotFound(err) is true for the
118 // returned error value err when the specified resource is not found.
119 Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error)
120}
121
122// GetterWithOptions is an object that retrieve a named RESTful resource and takes
123// additional options on the get request. It allows a caller to also receive the
124// subpath of the GET request.
125type GetterWithOptions interface {
126 // Get finds a resource in the storage by name and returns it.
127 // Although it can return an arbitrary error value, IsNotFound(err) is true for the
128 // returned error value err when the specified resource is not found.
129 // The options object passed to it is of the same type returned by the NewGetOptions
130 // method.
131 // TODO: Pass metav1.GetOptions.
132 Get(ctx context.Context, name string, options runtime.Object) (runtime.Object, error)
133
134 // NewGetOptions returns an empty options object that will be used to pass
135 // options to the Get method. It may return a bool and a string, if true, the
136 // value of the request path below the object will be included as the named
137 // string in the serialization of the runtime object. E.g., returning "path"
138 // will convert the trailing request scheme value to "path" in the map[string][]string
139 // passed to the converter.
140 NewGetOptions() (runtime.Object, bool, string)
141}
142
143type TableConvertor interface {
144 ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error)
145}
146
147// GracefulDeleter knows how to pass deletion options to allow delayed deletion of a
148// RESTful object.
149type GracefulDeleter interface {
150 // Delete finds a resource in the storage and deletes it.
151 // If options are provided, the resource will attempt to honor them or return an invalid
152 // request error.
153 // Although it can return an arbitrary error value, IsNotFound(err) is true for the
154 // returned error value err when the specified resource is not found.
155 // Delete *may* return the object that was deleted, or a status object indicating additional
156 // information about deletion.
157 // It also returns a boolean which is set to true if the resource was instantly
158 // deleted or false if it will be deleted asynchronously.
159 Delete(ctx context.Context, name string, options *metav1.DeleteOptions) (runtime.Object, bool, error)
160}
161
162// CollectionDeleter is an object that can delete a collection
163// of RESTful resources.
164type CollectionDeleter interface {
165 // DeleteCollection selects all resources in the storage matching given 'listOptions'
166 // and deletes them. If 'options' are provided, the resource will attempt to honor
167 // them or return an invalid request error.
168 // DeleteCollection may not be atomic - i.e. it may delete some objects and still
169 // return an error after it. On success, returns a list of deleted objects.
170 DeleteCollection(ctx context.Context, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error)
171}
172
173// Creater is an object that can create an instance of a RESTful object.
174type Creater interface {
175 // New returns an empty object that can be used with Create after request data has been put into it.
176 // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
177 New() runtime.Object
178
179 // Create creates a new version of a resource. If includeUninitialized is set, the object may be returned
180 // without completing initialization.
181 Create(ctx context.Context, obj runtime.Object, createValidation ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error)
182}
183
184// NamedCreater is an object that can create an instance of a RESTful object using a name parameter.
185type NamedCreater interface {
186 // New returns an empty object that can be used with Create after request data has been put into it.
187 // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
188 New() runtime.Object
189
190 // Create creates a new version of a resource. It expects a name parameter from the path.
191 // This is needed for create operations on subresources which include the name of the parent
192 // resource in the path. If includeUninitialized is set, the object may be returned without
193 // completing initialization.
194 Create(ctx context.Context, name string, obj runtime.Object, createValidation ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error)
195}
196
197// UpdatedObjectInfo provides information about an updated object to an Updater.
198// It requires access to the old object in order to return the newly updated object.
199type UpdatedObjectInfo interface {
200 // Returns preconditions built from the updated object, if applicable.
201 // May return nil, or a preconditions object containing nil fields,
202 // if no preconditions can be determined from the updated object.
203 Preconditions() *metav1.Preconditions
204
205 // UpdatedObject returns the updated object, given a context and old object.
206 // The only time an empty oldObj should be passed in is if a "create on update" is occurring (there is no oldObj).
207 UpdatedObject(ctx context.Context, oldObj runtime.Object) (newObj runtime.Object, err error)
208}
209
210// ValidateObjectFunc is a function to act on a given object. An error may be returned
211// if the hook cannot be completed. An ObjectFunc may NOT transform the provided
212// object.
213type ValidateObjectFunc func(obj runtime.Object) error
214
215// ValidateAllObjectFunc is a "admit everything" instance of ValidateObjectFunc.
216func ValidateAllObjectFunc(obj runtime.Object) error {
217 return nil
218}
219
220// ValidateObjectUpdateFunc is a function to act on a given object and its predecessor.
221// An error may be returned if the hook cannot be completed. An UpdateObjectFunc
222// may NOT transform the provided object.
223type ValidateObjectUpdateFunc func(obj, old runtime.Object) error
224
225// ValidateAllObjectUpdateFunc is a "admit everything" instance of ValidateObjectUpdateFunc.
226func ValidateAllObjectUpdateFunc(obj, old runtime.Object) error {
227 return nil
228}
229
230// Updater is an object that can update an instance of a RESTful object.
231type Updater interface {
232 // New returns an empty object that can be used with Update after request data has been put into it.
233 // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
234 New() runtime.Object
235
236 // Update finds a resource in the storage and updates it. Some implementations
237 // may allow updates creates the object - they should set the created boolean
238 // to true.
239 Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc) (runtime.Object, bool, error)
240}
241
242// CreaterUpdater is a storage object that must support both create and update.
243// Go prevents embedded interfaces that implement the same method.
244type CreaterUpdater interface {
245 Creater
246 Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc) (runtime.Object, bool, error)
247}
248
249// CreaterUpdater must satisfy the Updater interface.
250var _ Updater = CreaterUpdater(nil)
251
252// Patcher is a storage object that supports both get and update.
253type Patcher interface {
254 Getter
255 Updater
256}
257
258// Watcher should be implemented by all Storage objects that
259// want to offer the ability to watch for changes through the watch api.
260type Watcher interface {
261 // 'label' selects on labels; 'field' selects on the object's fields. Not all fields
262 // are supported; an error should be returned if 'field' tries to select on a field that
263 // isn't supported. 'resourceVersion' allows for continuing/starting a watch at a
264 // particular version.
265 Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error)
266}
267
268// StandardStorage is an interface covering the common verbs. Provided for testing whether a
269// resource satisfies the normal storage methods. Use Storage when passing opaque storage objects.
270type StandardStorage interface {
271 Getter
272 Lister
273 CreaterUpdater
274 GracefulDeleter
275 CollectionDeleter
276 Watcher
277}
278
279// Redirector know how to return a remote resource's location.
280type Redirector interface {
281 // ResourceLocation should return the remote location of the given resource, and an optional transport to use to request it, or an error.
282 ResourceLocation(ctx context.Context, id string) (remoteLocation *url.URL, transport http.RoundTripper, err error)
283}
284
285// Responder abstracts the normal response behavior for a REST method and is passed to callers that
286// may wish to handle the response directly in some cases, but delegate to the normal error or object
287// behavior in other cases.
288type Responder interface {
289 // Object writes the provided object to the response. Invoking this method multiple times is undefined.
290 Object(statusCode int, obj runtime.Object)
291 // Error writes the provided error to the response. This method may only be invoked once.
292 Error(err error)
293}
294
295// Connecter is a storage object that responds to a connection request.
296type Connecter interface {
297 // Connect returns an http.Handler that will handle the request/response for a given API invocation.
298 // The provided responder may be used for common API responses. The responder will write both status
299 // code and body, so the ServeHTTP method should exit after invoking the responder. The Handler will
300 // be used for a single API request and then discarded. The Responder is guaranteed to write to the
301 // same http.ResponseWriter passed to ServeHTTP.
302 Connect(ctx context.Context, id string, options runtime.Object, r Responder) (http.Handler, error)
303
304 // NewConnectOptions returns an empty options object that will be used to pass
305 // options to the Connect method. If nil, then a nil options object is passed to
306 // Connect. It may return a bool and a string. If true, the value of the request
307 // path below the object will be included as the named string in the serialization
308 // of the runtime object.
309 NewConnectOptions() (runtime.Object, bool, string)
310
311 // ConnectMethods returns the list of HTTP methods handled by Connect
312 ConnectMethods() []string
313}
314
315// ResourceStreamer is an interface implemented by objects that prefer to be streamed from the server
316// instead of decoded directly.
317type ResourceStreamer interface {
318 // InputStream should return an io.ReadCloser if the provided object supports streaming. The desired
319 // api version and an accept header (may be empty) are passed to the call. If no error occurs,
320 // the caller may return a flag indicating whether the result should be flushed as writes occur
321 // and a content type string that indicates the type of the stream.
322 // If a null stream is returned, a StatusNoContent response wil be generated.
323 InputStream(apiVersion, acceptHeader string) (stream io.ReadCloser, flush bool, mimeType string, err error)
324}
325
326// StorageMetadata is an optional interface that callers can implement to provide additional
327// information about their Storage objects.
328type StorageMetadata interface {
329 // ProducesMIMETypes returns a list of the MIME types the specified HTTP verb (GET, POST, DELETE,
330 // PATCH) can respond with.
331 ProducesMIMETypes(verb string) []string
332
333 // ProducesObject returns an object the specified HTTP verb respond with. It will overwrite storage object if
334 // it is not nil. Only the type of the return object matters, the value will be ignored.
335 ProducesObject(verb string) interface{}
336}
337
338// +k8s:deepcopy-gen=true
339// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
340// ConnectRequest is an object passed to admission control for Connect operations
341type ConnectRequest struct {
342 // Name is the name of the object on which the connect request was made
343 Name string
344
345 // Options is the options object passed to the connect request. See the NewConnectOptions method on Connecter
346 Options runtime.Object
347
348 // ResourcePath is the path for the resource in the REST server (ie. "pods/proxy")
349 ResourcePath string
350}
351
352func (obj *ConnectRequest) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }