2017-02-01 00:45:59 +00:00
|
|
|
/*
|
|
|
|
Copyright 2015 The Kubernetes Authors.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"golang.org/x/net/context"
|
2017-02-03 13:41:32 +00:00
|
|
|
"k8s.io/apimachinery/pkg/fields"
|
2017-02-01 00:45:59 +00:00
|
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
|
|
"k8s.io/apimachinery/pkg/types"
|
|
|
|
"k8s.io/apimachinery/pkg/watch"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Versioner abstracts setting and retrieving metadata fields from database response
|
|
|
|
// onto the object ot list.
|
|
|
|
type Versioner interface {
|
|
|
|
// UpdateObject sets storage metadata into an API object. Returns an error if the object
|
|
|
|
// cannot be updated correctly. May return nil if the requested object does not need metadata
|
|
|
|
// from database.
|
|
|
|
UpdateObject(obj runtime.Object, resourceVersion uint64) error
|
|
|
|
// UpdateList sets the resource version into an API list object. Returns an error if the object
|
|
|
|
// cannot be updated correctly. May return nil if the requested object does not need metadata
|
|
|
|
// from database.
|
|
|
|
UpdateList(obj runtime.Object, resourceVersion uint64) error
|
|
|
|
// ObjectResourceVersion returns the resource version (for persistence) of the specified object.
|
|
|
|
// Should return an error if the specified object does not have a persistable version.
|
|
|
|
ObjectResourceVersion(obj runtime.Object) (uint64, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ResponseMeta contains information about the database metadata that is associated with
|
|
|
|
// an object. It abstracts the actual underlying objects to prevent coupling with concrete
|
|
|
|
// database and to improve testability.
|
|
|
|
type ResponseMeta struct {
|
|
|
|
// TTL is the time to live of the node that contained the returned object. It may be
|
|
|
|
// zero or negative in some cases (objects may be expired after the requested
|
|
|
|
// expiration time due to server lag).
|
|
|
|
TTL int64
|
|
|
|
// The resource version of the node that contained the returned object.
|
|
|
|
ResourceVersion uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
// MatchValue defines a pair (<index name>, <value for that index>).
|
|
|
|
type MatchValue struct {
|
|
|
|
IndexName string
|
|
|
|
Value string
|
|
|
|
}
|
|
|
|
|
|
|
|
// TriggerPublisherFunc is a function that takes an object, and returns a list of pairs
|
|
|
|
// (<index name>, <index value for the given object>) for all indexes known
|
|
|
|
// to that function.
|
|
|
|
type TriggerPublisherFunc func(obj runtime.Object) []MatchValue
|
|
|
|
|
|
|
|
// FilterFunc takes an API object and returns true if the object satisfies some requirements.
|
|
|
|
// TODO: We will remove this type and use SelectionPredicate everywhere.
|
|
|
|
type FilterFunc func(obj runtime.Object) bool
|
|
|
|
|
|
|
|
// Everything accepts all objects.
|
|
|
|
var Everything = SelectionPredicate{
|
|
|
|
Label: labels.Everything(),
|
|
|
|
Field: fields.Everything(),
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass an UpdateFunc to Interface.GuaranteedUpdate to make an update
|
|
|
|
// that is guaranteed to succeed.
|
|
|
|
// See the comment for GuaranteedUpdate for more details.
|
|
|
|
type UpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error)
|
|
|
|
|
|
|
|
// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
|
|
|
|
type Preconditions struct {
|
|
|
|
// Specifies the target UID.
|
|
|
|
// +optional
|
|
|
|
UID *types.UID `json:"uid,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewUIDPreconditions returns a Preconditions with UID set.
|
|
|
|
func NewUIDPreconditions(uid string) *Preconditions {
|
|
|
|
u := types.UID(uid)
|
|
|
|
return &Preconditions{UID: &u}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Interface offers a common interface for object marshaling/unmarshaling operations and
|
|
|
|
// hides all the storage-related operations behind it.
|
|
|
|
type Interface interface {
|
|
|
|
// Returns Versioner associated with this interface.
|
|
|
|
Versioner() Versioner
|
|
|
|
|
|
|
|
// Create adds a new object at a key unless it already exists. 'ttl' is time-to-live
|
|
|
|
// in seconds (0 means forever). If no error is returned and out is not nil, out will be
|
|
|
|
// set to the read value from database.
|
|
|
|
Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error
|
|
|
|
|
|
|
|
// Delete removes the specified key and returns the value that existed at that spot.
|
|
|
|
// If key didn't exist, it will return NotFound storage error.
|
|
|
|
Delete(ctx context.Context, key string, out runtime.Object, preconditions *Preconditions) error
|
|
|
|
|
|
|
|
// Watch begins watching the specified key. Events are decoded into API objects,
|
|
|
|
// and any items selected by 'p' are sent down to returned watch.Interface.
|
|
|
|
// resourceVersion may be used to specify what version to begin watching,
|
|
|
|
// which should be the current resourceVersion, and no longer rv+1
|
|
|
|
// (e.g. reconnecting without missing any updates).
|
|
|
|
// If resource version is "0", this interface will get current object at given key
|
|
|
|
// and send it in an "ADDED" event, before watch starts.
|
|
|
|
Watch(ctx context.Context, key string, resourceVersion string, p SelectionPredicate) (watch.Interface, error)
|
|
|
|
|
|
|
|
// WatchList begins watching the specified key's items. Items are decoded into API
|
|
|
|
// objects and any item selected by 'p' are sent down to returned watch.Interface.
|
|
|
|
// resourceVersion may be used to specify what version to begin watching,
|
|
|
|
// which should be the current resourceVersion, and no longer rv+1
|
|
|
|
// (e.g. reconnecting without missing any updates).
|
|
|
|
// If resource version is "0", this interface will list current objects directory defined by key
|
|
|
|
// and send them in "ADDED" events, before watch starts.
|
|
|
|
WatchList(ctx context.Context, key string, resourceVersion string, p SelectionPredicate) (watch.Interface, error)
|
|
|
|
|
|
|
|
// Get unmarshals json found at key into objPtr. On a not found error, will either
|
|
|
|
// return a zero object of the requested type, or an error, depending on ignoreNotFound.
|
|
|
|
// Treats empty responses and nil response nodes exactly like a not found error.
|
|
|
|
// The returned contents may be delayed, but it is guaranteed that they will
|
|
|
|
// be have at least 'resourceVersion'.
|
|
|
|
Get(ctx context.Context, key string, resourceVersion string, objPtr runtime.Object, ignoreNotFound bool) error
|
|
|
|
|
|
|
|
// GetToList unmarshals json found at key and opaque it into *List api object
|
|
|
|
// (an object that satisfies the runtime.IsList definition).
|
|
|
|
// The returned contents may be delayed, but it is guaranteed that they will
|
|
|
|
// be have at least 'resourceVersion'.
|
|
|
|
GetToList(ctx context.Context, key string, resourceVersion string, p SelectionPredicate, listObj runtime.Object) error
|
|
|
|
|
|
|
|
// List unmarshalls jsons found at directory defined by key and opaque them
|
|
|
|
// into *List api object (an object that satisfies runtime.IsList definition).
|
|
|
|
// The returned contents may be delayed, but it is guaranteed that they will
|
|
|
|
// be have at least 'resourceVersion'.
|
|
|
|
List(ctx context.Context, key string, resourceVersion string, p SelectionPredicate, listObj runtime.Object) error
|
|
|
|
|
|
|
|
// GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType')
|
|
|
|
// retrying the update until success if there is index conflict.
|
|
|
|
// Note that object passed to tryUpdate may change across invocations of tryUpdate() if
|
|
|
|
// other writers are simultaneously updating it, so tryUpdate() needs to take into account
|
|
|
|
// the current contents of the object when deciding how the update object should look.
|
|
|
|
// If the key doesn't exist, it will return NotFound storage error if ignoreNotFound=false
|
|
|
|
// or zero value in 'ptrToType' parameter otherwise.
|
|
|
|
// If the object to update has the same value as previous, it won't do any update
|
|
|
|
// but will return the object in 'ptrToType' parameter.
|
|
|
|
// If 'suggestion' can contain zero or one element - in such case this can be used as
|
|
|
|
// a suggestion about the current version of the object to avoid read operation from
|
|
|
|
// storage to get it.
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
//
|
|
|
|
// s := /* implementation of Interface */
|
|
|
|
// err := s.GuaranteedUpdate(
|
|
|
|
// "myKey", &MyType{}, true,
|
|
|
|
// func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) {
|
|
|
|
// // Before each incovation of the user defined function, "input" is reset to
|
|
|
|
// // current contents for "myKey" in database.
|
|
|
|
// curr := input.(*MyType) // Guaranteed to succeed.
|
|
|
|
//
|
|
|
|
// // Make the modification
|
|
|
|
// curr.Counter++
|
|
|
|
//
|
|
|
|
// // Return the modified object - return an error to stop iterating. Return
|
|
|
|
// // a uint64 to alter the TTL on the object, or nil to keep it the same value.
|
|
|
|
// return cur, nil, nil
|
|
|
|
// }
|
|
|
|
// })
|
|
|
|
GuaranteedUpdate(
|
|
|
|
ctx context.Context, key string, ptrToType runtime.Object, ignoreNotFound bool,
|
|
|
|
precondtions *Preconditions, tryUpdate UpdateFunc, suggestion ...runtime.Object) error
|
|
|
|
}
|