blob: 227ab2b8ec3ac7da63803b256c029300a6ecee6e [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001/*
2Copyright 2015 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 storage
18
19import (
20 "context"
21
22 "k8s.io/apimachinery/pkg/fields"
23 "k8s.io/apimachinery/pkg/labels"
24 "k8s.io/apimachinery/pkg/runtime"
25 "k8s.io/apimachinery/pkg/types"
26 "k8s.io/apimachinery/pkg/watch"
27)
28
29// Versioner abstracts setting and retrieving metadata fields from database response
30// onto the object ot list. It is required to maintain storage invariants - updating an
31// object twice with the same data except for the ResourceVersion and SelfLink must be
32// a no-op. A resourceVersion of type uint64 is a 'raw' resourceVersion,
33// intended to be sent directly to or from the backend. A resourceVersion of
34// type string is a 'safe' resourceVersion, intended for consumption by users.
35type Versioner interface {
36 // UpdateObject sets storage metadata into an API object. Returns an error if the object
37 // cannot be updated correctly. May return nil if the requested object does not need metadata
38 // from database.
39 UpdateObject(obj runtime.Object, resourceVersion uint64) error
40 // UpdateList sets the resource version into an API list object. Returns an error if the object
41 // cannot be updated correctly. May return nil if the requested object does not need metadata
42 // from database. continueValue is optional and indicates that more results are available if
43 // the client passes that value to the server in a subsequent call.
44 UpdateList(obj runtime.Object, resourceVersion uint64, continueValue string) error
45 // PrepareObjectForStorage should set SelfLink and ResourceVersion to the empty value. Should
46 // return an error if the specified object cannot be updated.
47 PrepareObjectForStorage(obj runtime.Object) error
48 // ObjectResourceVersion returns the resource version (for persistence) of the specified object.
49 // Should return an error if the specified object does not have a persistable version.
50 ObjectResourceVersion(obj runtime.Object) (uint64, error)
51
52 // ParseWatchResourceVersion takes a resource version argument and
53 // converts it to the storage backend we should pass to helper.Watch().
54 // Because resourceVersion is an opaque value, the default watch
55 // behavior for non-zero watch is to watch the next value (if you pass
56 // "1", you will see updates from "2" onwards).
57 ParseWatchResourceVersion(resourceVersion string) (uint64, error)
58 // ParseListResourceVersion takes a resource version argument and
59 // converts it to the storage backend version. Appropriate for
60 // everything that's not intended as an argument for watch.
61 ParseListResourceVersion(resourceVersion string) (uint64, error)
62}
63
64// ResponseMeta contains information about the database metadata that is associated with
65// an object. It abstracts the actual underlying objects to prevent coupling with concrete
66// database and to improve testability.
67type ResponseMeta struct {
68 // TTL is the time to live of the node that contained the returned object. It may be
69 // zero or negative in some cases (objects may be expired after the requested
70 // expiration time due to server lag).
71 TTL int64
72 // The resource version of the node that contained the returned object.
73 ResourceVersion uint64
74}
75
76// MatchValue defines a pair (<index name>, <value for that index>).
77type MatchValue struct {
78 IndexName string
79 Value string
80}
81
82// TriggerPublisherFunc is a function that takes an object, and returns a list of pairs
83// (<index name>, <index value for the given object>) for all indexes known
84// to that function.
85type TriggerPublisherFunc func(obj runtime.Object) []MatchValue
86
87// Everything accepts all objects.
88var Everything = SelectionPredicate{
89 Label: labels.Everything(),
90 Field: fields.Everything(),
91 // TODO: split this into a new top level constant?
92 IncludeUninitialized: true,
93}
94
95// Pass an UpdateFunc to Interface.GuaranteedUpdate to make an update
96// that is guaranteed to succeed.
97// See the comment for GuaranteedUpdate for more details.
98type UpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error)
99
100// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
101type Preconditions struct {
102 // Specifies the target UID.
103 // +optional
104 UID *types.UID `json:"uid,omitempty"`
105}
106
107// NewUIDPreconditions returns a Preconditions with UID set.
108func NewUIDPreconditions(uid string) *Preconditions {
109 u := types.UID(uid)
110 return &Preconditions{UID: &u}
111}
112
113// Interface offers a common interface for object marshaling/unmarshaling operations and
114// hides all the storage-related operations behind it.
115type Interface interface {
116 // Returns Versioner associated with this interface.
117 Versioner() Versioner
118
119 // Create adds a new object at a key unless it already exists. 'ttl' is time-to-live
120 // in seconds (0 means forever). If no error is returned and out is not nil, out will be
121 // set to the read value from database.
122 Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error
123
124 // Delete removes the specified key and returns the value that existed at that spot.
125 // If key didn't exist, it will return NotFound storage error.
126 Delete(ctx context.Context, key string, out runtime.Object, preconditions *Preconditions) error
127
128 // Watch begins watching the specified key. Events are decoded into API objects,
129 // and any items selected by 'p' are sent down to returned watch.Interface.
130 // resourceVersion may be used to specify what version to begin watching,
131 // which should be the current resourceVersion, and no longer rv+1
132 // (e.g. reconnecting without missing any updates).
133 // If resource version is "0", this interface will get current object at given key
134 // and send it in an "ADDED" event, before watch starts.
135 Watch(ctx context.Context, key string, resourceVersion string, p SelectionPredicate) (watch.Interface, error)
136
137 // WatchList begins watching the specified key's items. Items are decoded into API
138 // objects and any item selected by 'p' are sent down to returned watch.Interface.
139 // resourceVersion may be used to specify what version to begin watching,
140 // which should be the current resourceVersion, and no longer rv+1
141 // (e.g. reconnecting without missing any updates).
142 // If resource version is "0", this interface will list current objects directory defined by key
143 // and send them in "ADDED" events, before watch starts.
144 WatchList(ctx context.Context, key string, resourceVersion string, p SelectionPredicate) (watch.Interface, error)
145
146 // Get unmarshals json found at key into objPtr. On a not found error, will either
147 // return a zero object of the requested type, or an error, depending on ignoreNotFound.
148 // Treats empty responses and nil response nodes exactly like a not found error.
149 // The returned contents may be delayed, but it is guaranteed that they will
150 // be have at least 'resourceVersion'.
151 Get(ctx context.Context, key string, resourceVersion string, objPtr runtime.Object, ignoreNotFound bool) error
152
153 // GetToList unmarshals json found at key and opaque it into *List api object
154 // (an object that satisfies the runtime.IsList definition).
155 // The returned contents may be delayed, but it is guaranteed that they will
156 // be have at least 'resourceVersion'.
157 GetToList(ctx context.Context, key string, resourceVersion string, p SelectionPredicate, listObj runtime.Object) error
158
159 // List unmarshalls jsons found at directory defined by key and opaque them
160 // into *List api object (an object that satisfies runtime.IsList definition).
161 // The returned contents may be delayed, but it is guaranteed that they will
162 // be have at least 'resourceVersion'.
163 List(ctx context.Context, key string, resourceVersion string, p SelectionPredicate, listObj runtime.Object) error
164
165 // GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType')
166 // retrying the update until success if there is index conflict.
167 // Note that object passed to tryUpdate may change across invocations of tryUpdate() if
168 // other writers are simultaneously updating it, so tryUpdate() needs to take into account
169 // the current contents of the object when deciding how the update object should look.
170 // If the key doesn't exist, it will return NotFound storage error if ignoreNotFound=false
171 // or zero value in 'ptrToType' parameter otherwise.
172 // If the object to update has the same value as previous, it won't do any update
173 // but will return the object in 'ptrToType' parameter.
174 // If 'suggestion' can contain zero or one element - in such case this can be used as
175 // a suggestion about the current version of the object to avoid read operation from
176 // storage to get it.
177 //
178 // Example:
179 //
180 // s := /* implementation of Interface */
181 // err := s.GuaranteedUpdate(
182 // "myKey", &MyType{}, true,
183 // func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) {
184 // // Before each incovation of the user defined function, "input" is reset to
185 // // current contents for "myKey" in database.
186 // curr := input.(*MyType) // Guaranteed to succeed.
187 //
188 // // Make the modification
189 // curr.Counter++
190 //
191 // // Return the modified object - return an error to stop iterating. Return
192 // // a uint64 to alter the TTL on the object, or nil to keep it the same value.
193 // return cur, nil, nil
194 // }
195 // })
196 GuaranteedUpdate(
197 ctx context.Context, key string, ptrToType runtime.Object, ignoreNotFound bool,
198 precondtions *Preconditions, tryUpdate UpdateFunc, suggestion ...runtime.Object) error
199
200 // Count returns number of different entries under the key (generally being path prefix).
201 Count(key string) (int64, error)
202}