Bump sigs.k8s.io/controller-runtime to v0.14.4 (#5507)
* Bump sigs.k8s.io/controller-runtime to v0.14.4 * Update gofmt
This commit is contained in:
94
vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go
generated
vendored
94
vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go
generated
vendored
@@ -24,6 +24,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -31,19 +33,20 @@ import (
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
endpointsrequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/audit"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/cacher/metrics"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/component-base/tracing"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/clock"
|
||||
utiltrace "k8s.io/utils/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -69,6 +72,10 @@ type Config struct {
|
||||
// An underlying storage.Versioner.
|
||||
Versioner storage.Versioner
|
||||
|
||||
// The GroupResource the cacher is caching. Used for disambiguating *unstructured.Unstructured (CRDs) in logging
|
||||
// and metrics.
|
||||
GroupResource schema.GroupResource
|
||||
|
||||
// The Cache will be caching objects of a given Type and assumes that they
|
||||
// are all stored under ResourcePrefix directory in the underlying database.
|
||||
ResourcePrefix string
|
||||
@@ -146,13 +153,13 @@ func (i *indexedWatchers) deleteWatcher(number int, value string, supported bool
|
||||
}
|
||||
}
|
||||
|
||||
func (i *indexedWatchers) terminateAll(objectType reflect.Type, done func(*cacheWatcher)) {
|
||||
func (i *indexedWatchers) terminateAll(groupResource schema.GroupResource, done func(*cacheWatcher)) {
|
||||
// note that we don't have to call setDrainInputBufferLocked method on the watchers
|
||||
// because we take advantage of the default value - stop immediately
|
||||
// also watchers that have had already its draining strategy set
|
||||
// are no longer available (they were removed from the allWatchers and the valueWatchers maps)
|
||||
if len(i.allWatchers) > 0 || len(i.valueWatchers) > 0 {
|
||||
klog.Warningf("Terminating all watchers from cacher %v", objectType)
|
||||
klog.Warningf("Terminating all watchers from cacher %v", groupResource)
|
||||
}
|
||||
i.allWatchers.terminateAll(done)
|
||||
for _, watchers := range i.valueWatchers {
|
||||
@@ -258,6 +265,8 @@ type Cacher struct {
|
||||
|
||||
// Expected type of objects in the underlying cache.
|
||||
objectType reflect.Type
|
||||
// Used for logging, to disambiguate *unstructured.Unstructured (CRDs)
|
||||
groupResource schema.GroupResource
|
||||
|
||||
// "sliding window" of recent changes of objects and the current state.
|
||||
watchCache *watchCache
|
||||
@@ -347,6 +356,7 @@ func NewCacherFromConfig(config Config) (*Cacher, error) {
|
||||
ready: newReady(),
|
||||
storage: config.Storage,
|
||||
objectType: objType,
|
||||
groupResource: config.GroupResource,
|
||||
versioner: config.Versioner,
|
||||
newFunc: config.NewFunc,
|
||||
indexedTrigger: indexedTrigger,
|
||||
@@ -377,7 +387,7 @@ func NewCacherFromConfig(config Config) (*Cacher, error) {
|
||||
}
|
||||
|
||||
watchCache := newWatchCache(
|
||||
config.KeyFunc, cacher.processEvent, config.GetAttrsFunc, config.Versioner, config.Indexers, config.Clock, objType)
|
||||
config.KeyFunc, cacher.processEvent, config.GetAttrsFunc, config.Versioner, config.Indexers, config.Clock, config.GroupResource)
|
||||
listerWatcher := NewCacherListerWatcher(config.Storage, config.ResourcePrefix, config.NewListFunc)
|
||||
reflectorName := "storage/cacher.go:" + config.ResourcePrefix
|
||||
|
||||
@@ -422,8 +432,8 @@ func (c *Cacher) startCaching(stopChannel <-chan struct{}) {
|
||||
c.watchCache.SetOnReplace(func() {
|
||||
successfulList = true
|
||||
c.ready.set(true)
|
||||
klog.V(1).Infof("cacher (%v): initialized", c.objectType.String())
|
||||
metrics.WatchCacheInitializations.WithLabelValues(c.objectType.String()).Inc()
|
||||
klog.V(1).Infof("cacher (%v): initialized", c.groupResource.String())
|
||||
metrics.WatchCacheInitializations.WithLabelValues(c.groupResource.String()).Inc()
|
||||
})
|
||||
defer func() {
|
||||
if successfulList {
|
||||
@@ -437,7 +447,7 @@ func (c *Cacher) startCaching(stopChannel <-chan struct{}) {
|
||||
// Also note that startCaching is called in a loop, so there's no need
|
||||
// to have another loop here.
|
||||
if err := c.reflector.ListAndWatch(stopChannel); err != nil {
|
||||
klog.Errorf("cacher (%v): unexpected ListAndWatch error: %v; reinitializing...", c.objectType.String(), err)
|
||||
klog.Errorf("cacher (%v): unexpected ListAndWatch error: %v; reinitializing...", c.groupResource.String(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,7 +518,16 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions
|
||||
// given that memory allocation may trigger GC and block the thread.
|
||||
// Also note that emptyFunc is a placeholder, until we will be able
|
||||
// to compute watcher.forget function (which has to happen under lock).
|
||||
watcher := newCacheWatcher(chanSize, filterWithAttrsFunction(key, pred), emptyFunc, c.versioner, deadline, pred.AllowWatchBookmarks, c.objectType, identifier)
|
||||
watcher := newCacheWatcher(
|
||||
chanSize,
|
||||
filterWithAttrsFunction(key, pred),
|
||||
emptyFunc,
|
||||
c.versioner,
|
||||
deadline,
|
||||
pred.AllowWatchBookmarks,
|
||||
c.groupResource,
|
||||
identifier,
|
||||
)
|
||||
|
||||
// We explicitly use thread unsafe version and do locking ourself to ensure that
|
||||
// no new events will be processed in the meantime. The watchCache will be unlocked
|
||||
@@ -576,7 +595,7 @@ func (c *Cacher) Get(ctx context.Context, key string, opts storage.GetOptions, o
|
||||
return err
|
||||
}
|
||||
|
||||
obj, exists, readResourceVersion, err := c.watchCache.WaitUntilFreshAndGet(getRV, key, nil)
|
||||
obj, exists, readResourceVersion, err := c.watchCache.WaitUntilFreshAndGet(ctx, getRV, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -615,9 +634,9 @@ func shouldDelegateList(opts storage.ListOptions) bool {
|
||||
return resourceVersion == "" || hasContinuation || hasLimit || opts.ResourceVersionMatch == metav1.ResourceVersionMatchExact
|
||||
}
|
||||
|
||||
func (c *Cacher) listItems(listRV uint64, key string, pred storage.SelectionPredicate, trace *utiltrace.Trace, recursive bool) ([]interface{}, uint64, string, error) {
|
||||
func (c *Cacher) listItems(ctx context.Context, listRV uint64, key string, pred storage.SelectionPredicate, recursive bool) ([]interface{}, uint64, string, error) {
|
||||
if !recursive {
|
||||
obj, exists, readResourceVersion, err := c.watchCache.WaitUntilFreshAndGet(listRV, key, trace)
|
||||
obj, exists, readResourceVersion, err := c.watchCache.WaitUntilFreshAndGet(ctx, listRV, key)
|
||||
if err != nil {
|
||||
return nil, 0, "", err
|
||||
}
|
||||
@@ -626,7 +645,7 @@ func (c *Cacher) listItems(listRV uint64, key string, pred storage.SelectionPred
|
||||
}
|
||||
return nil, readResourceVersion, "", nil
|
||||
}
|
||||
return c.watchCache.WaitUntilFreshAndList(listRV, pred.MatcherIndex(), trace)
|
||||
return c.watchCache.WaitUntilFreshAndList(ctx, listRV, pred.MatcherIndex())
|
||||
}
|
||||
|
||||
// GetList implements storage.Interface
|
||||
@@ -652,15 +671,15 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio
|
||||
return c.storage.GetList(ctx, key, opts, listObj)
|
||||
}
|
||||
|
||||
trace := utiltrace.New("cacher list",
|
||||
utiltrace.Field{"audit-id", endpointsrequest.GetAuditIDTruncated(ctx)},
|
||||
utiltrace.Field{Key: "type", Value: c.objectType.String()})
|
||||
defer trace.LogIfLong(500 * time.Millisecond)
|
||||
ctx, span := tracing.Start(ctx, "cacher list",
|
||||
attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)),
|
||||
attribute.Stringer("type", c.groupResource))
|
||||
defer span.End(500 * time.Millisecond)
|
||||
|
||||
if err := c.ready.wait(); err != nil {
|
||||
return errors.NewServiceUnavailable(err.Error())
|
||||
}
|
||||
trace.Step("Ready")
|
||||
span.AddEvent("Ready")
|
||||
|
||||
// List elements with at least 'listRV' from cache.
|
||||
listPtr, err := meta.GetItemsPtr(listObj)
|
||||
@@ -676,16 +695,16 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio
|
||||
}
|
||||
filter := filterWithAttrsFunction(key, pred)
|
||||
|
||||
objs, readResourceVersion, indexUsed, err := c.listItems(listRV, key, pred, trace, recursive)
|
||||
objs, readResourceVersion, indexUsed, err := c.listItems(ctx, listRV, key, pred, recursive)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trace.Step("Listed items from cache", utiltrace.Field{Key: "count", Value: len(objs)})
|
||||
span.AddEvent("Listed items from cache", attribute.Int("count", len(objs)))
|
||||
if len(objs) > listVal.Cap() && pred.Label.Empty() && pred.Field.Empty() {
|
||||
// Resize the slice appropriately, since we already know that none
|
||||
// of the elements will be filtered out.
|
||||
listVal.Set(reflect.MakeSlice(reflect.SliceOf(c.objectType.Elem()), 0, len(objs)))
|
||||
trace.Step("Resized result")
|
||||
span.AddEvent("Resized result")
|
||||
}
|
||||
for _, obj := range objs {
|
||||
elem, ok := obj.(*storeElement)
|
||||
@@ -696,7 +715,7 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio
|
||||
listVal.Set(reflect.Append(listVal, reflect.ValueOf(elem.Object).Elem()))
|
||||
}
|
||||
}
|
||||
trace.Step("Filtered items", utiltrace.Field{Key: "count", Value: listVal.Len()})
|
||||
span.AddEvent("Filtered items", attribute.Int("count", listVal.Len()))
|
||||
if c.versioner != nil {
|
||||
if err := c.versioner.UpdateList(listObj, readResourceVersion, "", nil); err != nil {
|
||||
return err
|
||||
@@ -757,7 +776,7 @@ func (c *Cacher) triggerValuesThreadUnsafe(event *watchCacheEvent) ([]string, bo
|
||||
func (c *Cacher) processEvent(event *watchCacheEvent) {
|
||||
if curLen := int64(len(c.incoming)); c.incomingHWM.Update(curLen) {
|
||||
// Monitor if this gets backed up, and how much.
|
||||
klog.V(1).Infof("cacher (%v): %v objects queued in incoming channel.", c.objectType.String(), curLen)
|
||||
klog.V(1).Infof("cacher (%v): %v objects queued in incoming channel.", c.groupResource.String(), curLen)
|
||||
}
|
||||
c.incoming <- *event
|
||||
}
|
||||
@@ -788,7 +807,7 @@ func (c *Cacher) dispatchEvents() {
|
||||
c.dispatchEvent(&event)
|
||||
}
|
||||
lastProcessedResourceVersion = event.ResourceVersion
|
||||
metrics.EventsCounter.WithLabelValues(c.objectType.String()).Inc()
|
||||
metrics.EventsCounter.WithLabelValues(c.groupResource.String()).Inc()
|
||||
case <-bookmarkTimer.C():
|
||||
bookmarkTimer.Reset(wait.Jitter(time.Second, 0.25))
|
||||
// Never send a bookmark event if we did not see an event here, this is fine
|
||||
@@ -1008,7 +1027,7 @@ func (c *Cacher) finishDispatching() {
|
||||
func (c *Cacher) terminateAllWatchers() {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.watchers.terminateAll(c.objectType, c.stopWatcherLocked)
|
||||
c.watchers.terminateAll(c.groupResource, c.stopWatcherLocked)
|
||||
}
|
||||
|
||||
func (c *Cacher) stopWatcherLocked(watcher *cacheWatcher) {
|
||||
@@ -1176,8 +1195,7 @@ type cacheWatcher struct {
|
||||
// save it here to send bookmark events before that.
|
||||
deadline time.Time
|
||||
allowWatchBookmarks bool
|
||||
// Object type of the cache watcher interests
|
||||
objectType reflect.Type
|
||||
groupResource schema.GroupResource
|
||||
|
||||
// human readable identifier that helps assigning cacheWatcher
|
||||
// instance with request
|
||||
@@ -1188,7 +1206,16 @@ type cacheWatcher struct {
|
||||
drainInputBuffer bool
|
||||
}
|
||||
|
||||
func newCacheWatcher(chanSize int, filter filterWithAttrsFunc, forget func(bool), versioner storage.Versioner, deadline time.Time, allowWatchBookmarks bool, objectType reflect.Type, identifier string) *cacheWatcher {
|
||||
func newCacheWatcher(
|
||||
chanSize int,
|
||||
filter filterWithAttrsFunc,
|
||||
forget func(bool),
|
||||
versioner storage.Versioner,
|
||||
deadline time.Time,
|
||||
allowWatchBookmarks bool,
|
||||
groupResource schema.GroupResource,
|
||||
identifier string,
|
||||
) *cacheWatcher {
|
||||
return &cacheWatcher{
|
||||
input: make(chan *watchCacheEvent, chanSize),
|
||||
result: make(chan watch.Event, chanSize),
|
||||
@@ -1199,7 +1226,7 @@ func newCacheWatcher(chanSize int, filter filterWithAttrsFunc, forget func(bool)
|
||||
versioner: versioner,
|
||||
deadline: deadline,
|
||||
allowWatchBookmarks: allowWatchBookmarks,
|
||||
objectType: objectType,
|
||||
groupResource: groupResource,
|
||||
identifier: identifier,
|
||||
}
|
||||
}
|
||||
@@ -1256,8 +1283,8 @@ func (c *cacheWatcher) add(event *watchCacheEvent, timer *time.Timer) bool {
|
||||
// This means that we couldn't send event to that watcher.
|
||||
// Since we don't want to block on it infinitely,
|
||||
// we simply terminate it.
|
||||
klog.V(1).Infof("Forcing %v watcher close due to unresponsiveness: %v. len(c.input) = %v, len(c.result) = %v", c.objectType.String(), c.identifier, len(c.input), len(c.result))
|
||||
metrics.TerminatedWatchersCounter.WithLabelValues(c.objectType.String()).Inc()
|
||||
klog.V(1).Infof("Forcing %v watcher close due to unresponsiveness: %v. len(c.input) = %v, len(c.result) = %v", c.groupResource.String(), c.identifier, len(c.input), len(c.result))
|
||||
metrics.TerminatedWatchersCounter.WithLabelValues(c.groupResource.String()).Inc()
|
||||
c.forget(false)
|
||||
}
|
||||
|
||||
@@ -1455,13 +1482,12 @@ func (c *cacheWatcher) processInterval(ctx context.Context, cacheInterval *watch
|
||||
initEventCount++
|
||||
}
|
||||
|
||||
objType := c.objectType.String()
|
||||
if initEventCount > 0 {
|
||||
metrics.InitCounter.WithLabelValues(objType).Add(float64(initEventCount))
|
||||
metrics.InitCounter.WithLabelValues(c.groupResource.String()).Add(float64(initEventCount))
|
||||
}
|
||||
processingTime := time.Since(startTime)
|
||||
if processingTime > initProcessThreshold {
|
||||
klog.V(2).Infof("processing %d initEvents of %s (%s) took %v", initEventCount, objType, c.identifier, processingTime)
|
||||
klog.V(2).Infof("processing %d initEvents of %s (%s) took %v", initEventCount, c.groupResource, c.identifier, processingTime)
|
||||
}
|
||||
|
||||
c.process(ctx, resourceVersion)
|
||||
|
||||
37
vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go
generated
vendored
37
vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go
generated
vendored
@@ -17,9 +17,9 @@ limitations under the License.
|
||||
package cacher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -28,13 +28,14 @@ import (
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/cacher/metrics"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/component-base/tracing"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/clock"
|
||||
utiltrace "k8s.io/utils/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -189,8 +190,8 @@ type watchCache struct {
|
||||
// An underlying storage.Versioner.
|
||||
versioner storage.Versioner
|
||||
|
||||
// cacher's objectType.
|
||||
objectType reflect.Type
|
||||
// cacher's group resource
|
||||
groupResource schema.GroupResource
|
||||
|
||||
// For testing cache interval invalidation.
|
||||
indexValidator indexValidator
|
||||
@@ -203,7 +204,7 @@ func newWatchCache(
|
||||
versioner storage.Versioner,
|
||||
indexers *cache.Indexers,
|
||||
clock clock.Clock,
|
||||
objectType reflect.Type) *watchCache {
|
||||
groupResource schema.GroupResource) *watchCache {
|
||||
wc := &watchCache{
|
||||
capacity: defaultLowerBoundCapacity,
|
||||
keyFunc: keyFunc,
|
||||
@@ -219,10 +220,9 @@ func newWatchCache(
|
||||
eventHandler: eventHandler,
|
||||
clock: clock,
|
||||
versioner: versioner,
|
||||
objectType: objectType,
|
||||
groupResource: groupResource,
|
||||
}
|
||||
objType := objectType.String()
|
||||
metrics.WatchCacheCapacity.WithLabelValues(objType).Set(float64(wc.capacity))
|
||||
metrics.WatchCacheCapacity.WithLabelValues(groupResource.String()).Set(float64(wc.capacity))
|
||||
wc.cond = sync.NewCond(wc.RLocker())
|
||||
wc.indexValidator = wc.isIndexValidLocked
|
||||
|
||||
@@ -387,7 +387,7 @@ func (w *watchCache) doCacheResizeLocked(capacity int) {
|
||||
newCache[i%capacity] = w.cache[i%w.capacity]
|
||||
}
|
||||
w.cache = newCache
|
||||
metrics.RecordsWatchCacheCapacityChange(w.objectType.String(), w.capacity, capacity)
|
||||
metrics.RecordsWatchCacheCapacityChange(w.groupResource.String(), w.capacity, capacity)
|
||||
w.capacity = capacity
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ func (w *watchCache) List() []interface{} {
|
||||
// waitUntilFreshAndBlock waits until cache is at least as fresh as given <resourceVersion>.
|
||||
// NOTE: This function acquired lock and doesn't release it.
|
||||
// You HAVE TO explicitly call w.RUnlock() after this function.
|
||||
func (w *watchCache) waitUntilFreshAndBlock(resourceVersion uint64, trace *utiltrace.Trace) error {
|
||||
func (w *watchCache) waitUntilFreshAndBlock(ctx context.Context, resourceVersion uint64) error {
|
||||
startTime := w.clock.Now()
|
||||
|
||||
// In case resourceVersion is 0, we accept arbitrarily stale result.
|
||||
@@ -450,9 +450,8 @@ func (w *watchCache) waitUntilFreshAndBlock(resourceVersion uint64, trace *utilt
|
||||
}
|
||||
|
||||
w.RLock()
|
||||
if trace != nil {
|
||||
trace.Step("watchCache locked acquired")
|
||||
}
|
||||
span := tracing.SpanFromContext(ctx)
|
||||
span.AddEvent("watchCache locked acquired")
|
||||
for w.resourceVersion < resourceVersion {
|
||||
if w.clock.Since(startTime) >= blockTimeout {
|
||||
// Request that the client retry after 'resourceVersionTooHighRetrySeconds' seconds.
|
||||
@@ -460,16 +459,14 @@ func (w *watchCache) waitUntilFreshAndBlock(resourceVersion uint64, trace *utilt
|
||||
}
|
||||
w.cond.Wait()
|
||||
}
|
||||
if trace != nil {
|
||||
trace.Step("watchCache fresh enough")
|
||||
}
|
||||
span.AddEvent("watchCache fresh enough")
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitUntilFreshAndList returns list of pointers to `storeElement` objects along
|
||||
// with their ResourceVersion and the name of the index, if any, that was used.
|
||||
func (w *watchCache) WaitUntilFreshAndList(resourceVersion uint64, matchValues []storage.MatchValue, trace *utiltrace.Trace) ([]interface{}, uint64, string, error) {
|
||||
err := w.waitUntilFreshAndBlock(resourceVersion, trace)
|
||||
func (w *watchCache) WaitUntilFreshAndList(ctx context.Context, resourceVersion uint64, matchValues []storage.MatchValue) ([]interface{}, uint64, string, error) {
|
||||
err := w.waitUntilFreshAndBlock(ctx, resourceVersion)
|
||||
defer w.RUnlock()
|
||||
if err != nil {
|
||||
return nil, 0, "", err
|
||||
@@ -488,8 +485,8 @@ func (w *watchCache) WaitUntilFreshAndList(resourceVersion uint64, matchValues [
|
||||
}
|
||||
|
||||
// WaitUntilFreshAndGet returns a pointers to <storeElement> object.
|
||||
func (w *watchCache) WaitUntilFreshAndGet(resourceVersion uint64, key string, trace *utiltrace.Trace) (interface{}, bool, uint64, error) {
|
||||
err := w.waitUntilFreshAndBlock(resourceVersion, trace)
|
||||
func (w *watchCache) WaitUntilFreshAndGet(ctx context.Context, resourceVersion uint64, key string) (interface{}, bool, uint64, error) {
|
||||
err := w.waitUntilFreshAndBlock(ctx, resourceVersion)
|
||||
defer w.RUnlock()
|
||||
if err != nil {
|
||||
return nil, false, 0, err
|
||||
|
||||
10
vendor/k8s.io/apiserver/pkg/storage/etcd3/compact.go
generated
vendored
10
vendor/k8s.io/apiserver/pkg/storage/etcd3/compact.go
generated
vendored
@@ -40,7 +40,7 @@ func init() {
|
||||
}
|
||||
|
||||
// StartCompactor starts a compactor in the background to compact old version of keys that's not needed.
|
||||
// By default, we save the most recent 10 minutes data and compact versions > 10minutes ago.
|
||||
// By default, we save the most recent 5 minutes data and compact versions > 5minutes ago.
|
||||
// It should be enough for slow watchers and to tolerate burst.
|
||||
// TODO: We might keep a longer history (12h) in the future once storage API can take advantage of past version of keys.
|
||||
func StartCompactor(ctx context.Context, client *clientv3.Client, compactInterval time.Duration) {
|
||||
@@ -84,7 +84,7 @@ func compactor(ctx context.Context, client *clientv3.Client, interval time.Durat
|
||||
// Technical details/insights:
|
||||
//
|
||||
// The protocol here is lease based. If one compactor CAS successfully, the others would know it when they fail in
|
||||
// CAS later and would try again in 10 minutes. If an APIServer crashed, another one would "take over" the lease.
|
||||
// CAS later and would try again in 5 minutes. If an APIServer crashed, another one would "take over" the lease.
|
||||
//
|
||||
// For example, in the following diagram, we have a compactor C1 doing compaction in t1, t2. Another compactor C2
|
||||
// at t1' (t1 < t1' < t2) would CAS fail, set its known oldRev to rev at t1', and try again in t2' (t2' > t2).
|
||||
@@ -100,14 +100,14 @@ func compactor(ctx context.Context, client *clientv3.Client, interval time.Durat
|
||||
// t0 t1 t2
|
||||
//
|
||||
// We have the guarantees:
|
||||
// - in normal cases, the interval is 10 minutes.
|
||||
// - in failover, the interval is >10m and <20m
|
||||
// - in normal cases, the interval is 5 minutes.
|
||||
// - in failover, the interval is >5m and <10m
|
||||
//
|
||||
// FAQ:
|
||||
// - What if time is not accurate? We don't care as long as someone did the compaction. Atomicity is ensured using
|
||||
// etcd API.
|
||||
// - What happened under heavy load scenarios? Initially, each apiserver will do only one compaction
|
||||
// every 10 minutes. This is very unlikely affecting or affected w.r.t. server load.
|
||||
// every 5 minutes. This is very unlikely affecting or affected w.r.t. server load.
|
||||
|
||||
var compactTime int64
|
||||
var rev int64
|
||||
|
||||
5
vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go
generated
vendored
5
vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go
generated
vendored
@@ -57,8 +57,9 @@ var (
|
||||
)
|
||||
dbTotalSize = compbasemetrics.NewGaugeVec(
|
||||
&compbasemetrics.GaugeOpts{
|
||||
Name: "etcd_db_total_size_in_bytes",
|
||||
Help: "Total size of the etcd database file physically allocated in bytes.",
|
||||
Subsystem: "apiserver",
|
||||
Name: "storage_db_total_size_in_bytes",
|
||||
Help: "Total size of the storage database file physically allocated in bytes.",
|
||||
StabilityLevel: compbasemetrics.ALPHA,
|
||||
},
|
||||
[]string{"endpoint"},
|
||||
|
||||
254
vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go
generated
vendored
254
vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go
generated
vendored
@@ -27,6 +27,7 @@ import (
|
||||
"time"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
@@ -37,14 +38,14 @@ import (
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
endpointsrequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/audit"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/etcd3/metrics"
|
||||
"k8s.io/apiserver/pkg/storage/value"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-base/tracing"
|
||||
"k8s.io/klog/v2"
|
||||
utiltrace "k8s.io/utils/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -98,19 +99,24 @@ func New(c *clientv3.Client, codec runtime.Codec, newFunc func() runtime.Object,
|
||||
|
||||
func newStore(c *clientv3.Client, codec runtime.Codec, newFunc func() runtime.Object, prefix string, groupResource schema.GroupResource, transformer value.Transformer, pagingEnabled bool, leaseManagerConfig LeaseManagerConfig) *store {
|
||||
versioner := storage.APIObjectVersioner{}
|
||||
// for compatibility with etcd2 impl.
|
||||
// no-op for default prefix of '/registry'.
|
||||
// keeps compatibility with etcd2 impl for custom prefixes that don't start with '/'
|
||||
pathPrefix := path.Join("/", prefix)
|
||||
if !strings.HasSuffix(pathPrefix, "/") {
|
||||
// Ensure the pathPrefix ends in "/" here to simplify key concatenation later.
|
||||
pathPrefix += "/"
|
||||
}
|
||||
result := &store{
|
||||
client: c,
|
||||
codec: codec,
|
||||
versioner: versioner,
|
||||
transformer: transformer,
|
||||
pagingEnabled: pagingEnabled,
|
||||
// for compatibility with etcd2 impl.
|
||||
// no-op for default prefix of '/registry'.
|
||||
// keeps compatibility with etcd2 impl for custom prefixes that don't start with '/'
|
||||
pathPrefix: path.Join("/", prefix),
|
||||
client: c,
|
||||
codec: codec,
|
||||
versioner: versioner,
|
||||
transformer: transformer,
|
||||
pagingEnabled: pagingEnabled,
|
||||
pathPrefix: pathPrefix,
|
||||
groupResource: groupResource,
|
||||
groupResourceString: groupResource.String(),
|
||||
watcher: newWatcher(c, codec, newFunc, versioner, transformer),
|
||||
watcher: newWatcher(c, codec, groupResource, newFunc, versioner),
|
||||
leaseManager: newDefaultLeaseManager(c, leaseManagerConfig),
|
||||
}
|
||||
return result
|
||||
@@ -123,10 +129,13 @@ func (s *store) Versioner() storage.Versioner {
|
||||
|
||||
// Get implements storage.Interface.Get.
|
||||
func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, out runtime.Object) error {
|
||||
key = path.Join(s.pathPrefix, key)
|
||||
preparedKey, err := s.prepareKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
startTime := time.Now()
|
||||
getResp, err := s.client.KV.Get(ctx, key)
|
||||
metrics.RecordEtcdRequestLatency("get", getTypeName(out), startTime)
|
||||
getResp, err := s.client.KV.Get(ctx, preparedKey)
|
||||
metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -138,11 +147,11 @@ func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, ou
|
||||
if opts.IgnoreNotFound {
|
||||
return runtime.SetZeroValue(out)
|
||||
}
|
||||
return storage.NewKeyNotFoundError(key, 0)
|
||||
return storage.NewKeyNotFoundError(preparedKey, 0)
|
||||
}
|
||||
kv := getResp.Kvs[0]
|
||||
|
||||
data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(key))
|
||||
data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(preparedKey))
|
||||
if err != nil {
|
||||
return storage.NewInternalError(err.Error())
|
||||
}
|
||||
@@ -152,58 +161,68 @@ func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, ou
|
||||
|
||||
// Create implements storage.Interface.Create.
|
||||
func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error {
|
||||
trace := utiltrace.New("Create etcd3",
|
||||
utiltrace.Field{"audit-id", endpointsrequest.GetAuditIDTruncated(ctx)},
|
||||
utiltrace.Field{"key", key},
|
||||
utiltrace.Field{"type", getTypeName(obj)},
|
||||
preparedKey, err := s.prepareKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx, span := tracing.Start(ctx, "Create etcd3",
|
||||
attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)),
|
||||
attribute.String("key", key),
|
||||
attribute.String("type", getTypeName(obj)),
|
||||
attribute.String("resource", s.groupResourceString),
|
||||
)
|
||||
defer trace.LogIfLong(500 * time.Millisecond)
|
||||
defer span.End(500 * time.Millisecond)
|
||||
if version, err := s.versioner.ObjectResourceVersion(obj); err == nil && version != 0 {
|
||||
return errors.New("resourceVersion should not be set on objects to be created")
|
||||
}
|
||||
if err := s.versioner.PrepareObjectForStorage(obj); err != nil {
|
||||
return fmt.Errorf("PrepareObjectForStorage failed: %v", err)
|
||||
}
|
||||
trace.Step("About to Encode")
|
||||
span.AddEvent("About to Encode")
|
||||
data, err := runtime.Encode(s.codec, obj)
|
||||
trace.Step("Encode finished", utiltrace.Field{"len", len(data)}, utiltrace.Field{"err", err})
|
||||
if err != nil {
|
||||
span.AddEvent("Encode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error()))
|
||||
return err
|
||||
}
|
||||
key = path.Join(s.pathPrefix, key)
|
||||
span.AddEvent("Encode succeeded", attribute.Int("len", len(data)))
|
||||
|
||||
opts, err := s.ttlOpts(ctx, int64(ttl))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newData, err := s.transformer.TransformToStorage(ctx, data, authenticatedDataString(key))
|
||||
trace.Step("TransformToStorage finished", utiltrace.Field{"err", err})
|
||||
newData, err := s.transformer.TransformToStorage(ctx, data, authenticatedDataString(preparedKey))
|
||||
if err != nil {
|
||||
span.AddEvent("TransformToStorage failed", attribute.String("err", err.Error()))
|
||||
return storage.NewInternalError(err.Error())
|
||||
}
|
||||
span.AddEvent("TransformToStorage succeeded")
|
||||
|
||||
startTime := time.Now()
|
||||
txnResp, err := s.client.KV.Txn(ctx).If(
|
||||
notFound(key),
|
||||
notFound(preparedKey),
|
||||
).Then(
|
||||
clientv3.OpPut(key, string(newData), opts...),
|
||||
clientv3.OpPut(preparedKey, string(newData), opts...),
|
||||
).Commit()
|
||||
metrics.RecordEtcdRequestLatency("create", getTypeName(obj), startTime)
|
||||
trace.Step("Txn call finished", utiltrace.Field{"err", err})
|
||||
metrics.RecordEtcdRequestLatency("create", s.groupResourceString, startTime)
|
||||
if err != nil {
|
||||
span.AddEvent("Txn call failed", attribute.String("err", err.Error()))
|
||||
return err
|
||||
}
|
||||
span.AddEvent("Txn call succeeded")
|
||||
|
||||
if !txnResp.Succeeded {
|
||||
return storage.NewKeyExistsError(key, 0)
|
||||
return storage.NewKeyExistsError(preparedKey, 0)
|
||||
}
|
||||
|
||||
if out != nil {
|
||||
putResp := txnResp.Responses[0].GetResponsePut()
|
||||
err = decode(s.codec, s.versioner, data, out, putResp.Header.Revision)
|
||||
trace.Step("decode finished", utiltrace.Field{"len", len(data)}, utiltrace.Field{"err", err})
|
||||
return err
|
||||
if err != nil {
|
||||
span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error()))
|
||||
return err
|
||||
}
|
||||
span.AddEvent("decode succeeded", attribute.Int("len", len(data)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -212,12 +231,15 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object,
|
||||
func (s *store) Delete(
|
||||
ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions,
|
||||
validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error {
|
||||
preparedKey, err := s.prepareKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v, err := conversion.EnforcePtr(out)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to convert output object to pointer: %v", err)
|
||||
}
|
||||
key = path.Join(s.pathPrefix, key)
|
||||
return s.conditionalDelete(ctx, key, out, v, preconditions, validateDeletion, cachedExistingObject)
|
||||
return s.conditionalDelete(ctx, preparedKey, out, v, preconditions, validateDeletion, cachedExistingObject)
|
||||
}
|
||||
|
||||
func (s *store) conditionalDelete(
|
||||
@@ -226,7 +248,7 @@ func (s *store) conditionalDelete(
|
||||
getCurrentState := func() (*objState, error) {
|
||||
startTime := time.Now()
|
||||
getResp, err := s.client.KV.Get(ctx, key)
|
||||
metrics.RecordEtcdRequestLatency("get", getTypeName(out), startTime)
|
||||
metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -308,7 +330,7 @@ func (s *store) conditionalDelete(
|
||||
).Else(
|
||||
clientv3.OpGet(key),
|
||||
).Commit()
|
||||
metrics.RecordEtcdRequestLatency("delete", getTypeName(out), startTime)
|
||||
metrics.RecordEtcdRequestLatency("delete", s.groupResourceString, startTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -322,7 +344,15 @@ func (s *store) conditionalDelete(
|
||||
origStateIsCurrent = true
|
||||
continue
|
||||
}
|
||||
return decode(s.codec, s.versioner, origState.data, out, origState.rev)
|
||||
|
||||
if len(txnResp.Responses) == 0 || txnResp.Responses[0].GetResponseDeleteRange() == nil {
|
||||
return errors.New(fmt.Sprintf("invalid DeleteRange response: %v", txnResp.Responses))
|
||||
}
|
||||
deleteResp := txnResp.Responses[0].GetResponseDeleteRange()
|
||||
if deleteResp.Header == nil {
|
||||
return errors.New("invalid DeleteRange response - nil header")
|
||||
}
|
||||
return decode(s.codec, s.versioner, origState.data, out, deleteResp.Header.Revision)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,26 +360,30 @@ func (s *store) conditionalDelete(
|
||||
func (s *store) GuaranteedUpdate(
|
||||
ctx context.Context, key string, destination runtime.Object, ignoreNotFound bool,
|
||||
preconditions *storage.Preconditions, tryUpdate storage.UpdateFunc, cachedExistingObject runtime.Object) error {
|
||||
trace := utiltrace.New("GuaranteedUpdate etcd3",
|
||||
utiltrace.Field{"audit-id", endpointsrequest.GetAuditIDTruncated(ctx)},
|
||||
utiltrace.Field{"key", key},
|
||||
utiltrace.Field{"type", getTypeName(destination)})
|
||||
defer trace.LogIfLong(500 * time.Millisecond)
|
||||
preparedKey, err := s.prepareKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx, span := tracing.Start(ctx, "GuaranteedUpdate etcd3",
|
||||
attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)),
|
||||
attribute.String("key", key),
|
||||
attribute.String("type", getTypeName(destination)),
|
||||
attribute.String("resource", s.groupResourceString))
|
||||
defer span.End(500 * time.Millisecond)
|
||||
|
||||
v, err := conversion.EnforcePtr(destination)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to convert output object to pointer: %v", err)
|
||||
}
|
||||
key = path.Join(s.pathPrefix, key)
|
||||
|
||||
getCurrentState := func() (*objState, error) {
|
||||
startTime := time.Now()
|
||||
getResp, err := s.client.KV.Get(ctx, key)
|
||||
metrics.RecordEtcdRequestLatency("get", getTypeName(destination), startTime)
|
||||
getResp, err := s.client.KV.Get(ctx, preparedKey)
|
||||
metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.getState(ctx, getResp, key, v, ignoreNotFound)
|
||||
return s.getState(ctx, getResp, preparedKey, v, ignoreNotFound)
|
||||
}
|
||||
|
||||
var origState *objState
|
||||
@@ -363,11 +397,11 @@ func (s *store) GuaranteedUpdate(
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trace.Step("initial value restored")
|
||||
span.AddEvent("initial value restored")
|
||||
|
||||
transformContext := authenticatedDataString(key)
|
||||
transformContext := authenticatedDataString(preparedKey)
|
||||
for {
|
||||
if err := preconditions.Check(key, origState.obj); err != nil {
|
||||
if err := preconditions.Check(preparedKey, origState.obj); err != nil {
|
||||
// If our data is already up to date, return the error
|
||||
if origStateIsCurrent {
|
||||
return err
|
||||
@@ -412,12 +446,13 @@ func (s *store) GuaranteedUpdate(
|
||||
continue
|
||||
}
|
||||
|
||||
trace.Step("About to Encode")
|
||||
span.AddEvent("About to Encode")
|
||||
data, err := runtime.Encode(s.codec, ret)
|
||||
trace.Step("Encode finished", utiltrace.Field{"len", len(data)}, utiltrace.Field{"err", err})
|
||||
if err != nil {
|
||||
span.AddEvent("Encode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error()))
|
||||
return err
|
||||
}
|
||||
span.AddEvent("Encode succeeded", attribute.Int("len", len(data)))
|
||||
if !origState.stale && bytes.Equal(data, origState.data) {
|
||||
// if we skipped the original Get in this loop, we must refresh from
|
||||
// etcd in order to be sure the data in the store is equivalent to
|
||||
@@ -440,47 +475,53 @@ func (s *store) GuaranteedUpdate(
|
||||
}
|
||||
|
||||
newData, err := s.transformer.TransformToStorage(ctx, data, transformContext)
|
||||
trace.Step("TransformToStorage finished", utiltrace.Field{"err", err})
|
||||
if err != nil {
|
||||
span.AddEvent("TransformToStorage failed", attribute.String("err", err.Error()))
|
||||
return storage.NewInternalError(err.Error())
|
||||
}
|
||||
span.AddEvent("TransformToStorage succeeded")
|
||||
|
||||
opts, err := s.ttlOpts(ctx, int64(ttl))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trace.Step("Transaction prepared")
|
||||
span.AddEvent("Transaction prepared")
|
||||
|
||||
startTime := time.Now()
|
||||
txnResp, err := s.client.KV.Txn(ctx).If(
|
||||
clientv3.Compare(clientv3.ModRevision(key), "=", origState.rev),
|
||||
clientv3.Compare(clientv3.ModRevision(preparedKey), "=", origState.rev),
|
||||
).Then(
|
||||
clientv3.OpPut(key, string(newData), opts...),
|
||||
clientv3.OpPut(preparedKey, string(newData), opts...),
|
||||
).Else(
|
||||
clientv3.OpGet(key),
|
||||
clientv3.OpGet(preparedKey),
|
||||
).Commit()
|
||||
metrics.RecordEtcdRequestLatency("update", getTypeName(destination), startTime)
|
||||
trace.Step("Txn call finished", utiltrace.Field{"err", err})
|
||||
metrics.RecordEtcdRequestLatency("update", s.groupResourceString, startTime)
|
||||
if err != nil {
|
||||
span.AddEvent("Txn call failed", attribute.String("err", err.Error()))
|
||||
return err
|
||||
}
|
||||
trace.Step("Transaction committed")
|
||||
span.AddEvent("Txn call completed")
|
||||
span.AddEvent("Transaction committed")
|
||||
if !txnResp.Succeeded {
|
||||
getResp := (*clientv3.GetResponse)(txnResp.Responses[0].GetResponseRange())
|
||||
klog.V(4).Infof("GuaranteedUpdate of %s failed because of a conflict, going to retry", key)
|
||||
origState, err = s.getState(ctx, getResp, key, v, ignoreNotFound)
|
||||
klog.V(4).Infof("GuaranteedUpdate of %s failed because of a conflict, going to retry", preparedKey)
|
||||
origState, err = s.getState(ctx, getResp, preparedKey, v, ignoreNotFound)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trace.Step("Retry value restored")
|
||||
span.AddEvent("Retry value restored")
|
||||
origStateIsCurrent = true
|
||||
continue
|
||||
}
|
||||
putResp := txnResp.Responses[0].GetResponsePut()
|
||||
|
||||
err = decode(s.codec, s.versioner, data, destination, putResp.Header.Revision)
|
||||
trace.Step("decode finished", utiltrace.Field{"len", len(data)}, utiltrace.Field{"err", err})
|
||||
return err
|
||||
if err != nil {
|
||||
span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error()))
|
||||
return err
|
||||
}
|
||||
span.AddEvent("decode succeeded", attribute.Int("len", len(data)))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,18 +543,21 @@ func getNewItemFunc(listObj runtime.Object, v reflect.Value) func() runtime.Obje
|
||||
}
|
||||
|
||||
func (s *store) Count(key string) (int64, error) {
|
||||
key = path.Join(s.pathPrefix, key)
|
||||
preparedKey, err := s.prepareKey(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// We need to make sure the key ended with "/" so that we only get children "directories".
|
||||
// e.g. if we have key "/a", "/a/b", "/ab", getting keys with prefix "/a" will return all three,
|
||||
// while with prefix "/a/" will return only "/a/b" which is the correct answer.
|
||||
if !strings.HasSuffix(key, "/") {
|
||||
key += "/"
|
||||
if !strings.HasSuffix(preparedKey, "/") {
|
||||
preparedKey += "/"
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
getResp, err := s.client.KV.Get(context.Background(), key, clientv3.WithRange(clientv3.GetPrefixRangeEnd(key)), clientv3.WithCountOnly())
|
||||
metrics.RecordEtcdRequestLatency("listWithCount", key, startTime)
|
||||
getResp, err := s.client.KV.Get(context.Background(), preparedKey, clientv3.WithRange(clientv3.GetPrefixRangeEnd(preparedKey)), clientv3.WithCountOnly())
|
||||
metrics.RecordEtcdRequestLatency("listWithCount", preparedKey, startTime)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -522,18 +566,22 @@ func (s *store) Count(key string) (int64, error) {
|
||||
|
||||
// GetList implements storage.Interface.
|
||||
func (s *store) GetList(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error {
|
||||
preparedKey, err := s.prepareKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recursive := opts.Recursive
|
||||
resourceVersion := opts.ResourceVersion
|
||||
match := opts.ResourceVersionMatch
|
||||
pred := opts.Predicate
|
||||
trace := utiltrace.New(fmt.Sprintf("List(recursive=%v) etcd3", recursive),
|
||||
utiltrace.Field{"audit-id", endpointsrequest.GetAuditIDTruncated(ctx)},
|
||||
utiltrace.Field{"key", key},
|
||||
utiltrace.Field{"resourceVersion", resourceVersion},
|
||||
utiltrace.Field{"resourceVersionMatch", match},
|
||||
utiltrace.Field{"limit", pred.Limit},
|
||||
utiltrace.Field{"continue", pred.Continue})
|
||||
defer trace.LogIfLong(500 * time.Millisecond)
|
||||
ctx, span := tracing.Start(ctx, fmt.Sprintf("List(recursive=%v) etcd3", recursive),
|
||||
attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)),
|
||||
attribute.String("key", key),
|
||||
attribute.String("resourceVersion", resourceVersion),
|
||||
attribute.String("resourceVersionMatch", string(match)),
|
||||
attribute.Int("limit", int(pred.Limit)),
|
||||
attribute.String("continue", pred.Continue))
|
||||
defer span.End(500 * time.Millisecond)
|
||||
listPtr, err := meta.GetItemsPtr(listObj)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -542,16 +590,15 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption
|
||||
if err != nil || v.Kind() != reflect.Slice {
|
||||
return fmt.Errorf("need ptr to slice: %v", err)
|
||||
}
|
||||
key = path.Join(s.pathPrefix, key)
|
||||
|
||||
// For recursive lists, we need to make sure the key ended with "/" so that we only
|
||||
// get children "directories". e.g. if we have key "/a", "/a/b", "/ab", getting keys
|
||||
// with prefix "/a" will return all three, while with prefix "/a/" will return only
|
||||
// "/a/b" which is the correct answer.
|
||||
if recursive && !strings.HasSuffix(key, "/") {
|
||||
key += "/"
|
||||
if recursive && !strings.HasSuffix(preparedKey, "/") {
|
||||
preparedKey += "/"
|
||||
}
|
||||
keyPrefix := key
|
||||
keyPrefix := preparedKey
|
||||
|
||||
// set the appropriate clientv3 options to filter the returned data set
|
||||
var limitOption *clientv3.OpOption
|
||||
@@ -590,7 +637,7 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption
|
||||
|
||||
rangeEnd := clientv3.GetPrefixRangeEnd(keyPrefix)
|
||||
options = append(options, clientv3.WithRange(rangeEnd))
|
||||
key = continueKey
|
||||
preparedKey = continueKey
|
||||
|
||||
// If continueRV > 0, the LIST request needs a specific resource version.
|
||||
// continueRV==0 is invalid.
|
||||
@@ -657,11 +704,11 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption
|
||||
}()
|
||||
for {
|
||||
startTime := time.Now()
|
||||
getResp, err = s.client.KV.Get(ctx, key, options...)
|
||||
getResp, err = s.client.KV.Get(ctx, preparedKey, options...)
|
||||
if recursive {
|
||||
metrics.RecordEtcdRequestLatency("list", getTypeName(listPtr), startTime)
|
||||
metrics.RecordEtcdRequestLatency("list", s.groupResourceString, startTime)
|
||||
} else {
|
||||
metrics.RecordEtcdRequestLatency("get", getTypeName(listPtr), startTime)
|
||||
metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime)
|
||||
}
|
||||
if err != nil {
|
||||
return interpretListError(err, len(pred.Continue) > 0, continueKey, keyPrefix)
|
||||
@@ -729,7 +776,7 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption
|
||||
}
|
||||
*limitOption = clientv3.WithLimit(limit)
|
||||
}
|
||||
key = string(lastKey) + "\x00"
|
||||
preparedKey = string(lastKey) + "\x00"
|
||||
if withRev == 0 {
|
||||
withRev = returnedRV
|
||||
options = append(options, clientv3.WithRev(withRev))
|
||||
@@ -794,12 +841,15 @@ func growSlice(v reflect.Value, maxCapacity int, sizes ...int) {
|
||||
|
||||
// Watch implements storage.Interface.Watch.
|
||||
func (s *store) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) {
|
||||
preparedKey, err := s.prepareKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rev, err := s.versioner.ParseResourceVersion(opts.ResourceVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key = path.Join(s.pathPrefix, key)
|
||||
return s.watcher.Watch(ctx, key, int64(rev), opts.Recursive, opts.ProgressNotify, opts.Predicate)
|
||||
return s.watcher.Watch(ctx, preparedKey, int64(rev), opts.Recursive, opts.ProgressNotify, s.transformer, opts.Predicate)
|
||||
}
|
||||
|
||||
func (s *store) getState(ctx context.Context, getResp *clientv3.GetResponse, key string, v reflect.Value, ignoreNotFound bool) (*objState, error) {
|
||||
@@ -911,6 +961,30 @@ func (s *store) validateMinimumResourceVersion(minimumResourceVersion string, ac
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *store) prepareKey(key string) (string, error) {
|
||||
if key == ".." ||
|
||||
strings.HasPrefix(key, "../") ||
|
||||
strings.HasSuffix(key, "/..") ||
|
||||
strings.Contains(key, "/../") {
|
||||
return "", fmt.Errorf("invalid key: %q", key)
|
||||
}
|
||||
if key == "." ||
|
||||
strings.HasPrefix(key, "./") ||
|
||||
strings.HasSuffix(key, "/.") ||
|
||||
strings.Contains(key, "/./") {
|
||||
return "", fmt.Errorf("invalid key: %q", key)
|
||||
}
|
||||
if key == "" || key == "/" {
|
||||
return "", fmt.Errorf("empty key: %q", key)
|
||||
}
|
||||
// We ensured that pathPrefix ends in '/' in construction, so skip any leading '/' in the key now.
|
||||
startIndex := 0
|
||||
if key[0] == '/' {
|
||||
startIndex = 1
|
||||
}
|
||||
return s.pathPrefix + key[startIndex:], nil
|
||||
}
|
||||
|
||||
// decode decodes value of bytes into object. It will also set the object resource version to rev.
|
||||
// On success, objPtr would be set to the object.
|
||||
func decode(codec runtime.Codec, versioner storage.Versioner, value []byte, objPtr runtime.Object, rev int64) error {
|
||||
|
||||
57
vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go
generated
vendored
57
vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go
generated
vendored
@@ -18,7 +18,6 @@ package etcd3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
@@ -28,6 +27,7 @@ import (
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/etcd3/metrics"
|
||||
@@ -47,16 +47,6 @@ const (
|
||||
// fatalOnDecodeError is used during testing to panic the server if watcher encounters a decoding error
|
||||
var fatalOnDecodeError = false
|
||||
|
||||
// errTestingDecode is the only error that testingDeferOnDecodeError catches during a panic
|
||||
var errTestingDecode = errors.New("sentinel error only used during testing to indicate watch decoding error")
|
||||
|
||||
// testingDeferOnDecodeError is used during testing to recover from a panic caused by errTestingDecode, all other values continue to panic
|
||||
func testingDeferOnDecodeError() {
|
||||
if r := recover(); r != nil && r != errTestingDecode {
|
||||
panic(r)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
// check to see if we are running in a test environment
|
||||
TestOnlySetFatalOnDecodeError(true)
|
||||
@@ -69,17 +59,18 @@ func TestOnlySetFatalOnDecodeError(b bool) {
|
||||
}
|
||||
|
||||
type watcher struct {
|
||||
client *clientv3.Client
|
||||
codec runtime.Codec
|
||||
newFunc func() runtime.Object
|
||||
objectType string
|
||||
versioner storage.Versioner
|
||||
transformer value.Transformer
|
||||
client *clientv3.Client
|
||||
codec runtime.Codec
|
||||
newFunc func() runtime.Object
|
||||
objectType string
|
||||
groupResource schema.GroupResource
|
||||
versioner storage.Versioner
|
||||
}
|
||||
|
||||
// watchChan implements watch.Interface.
|
||||
type watchChan struct {
|
||||
watcher *watcher
|
||||
transformer value.Transformer
|
||||
key string
|
||||
initialRev int64
|
||||
recursive bool
|
||||
@@ -92,13 +83,13 @@ type watchChan struct {
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
func newWatcher(client *clientv3.Client, codec runtime.Codec, newFunc func() runtime.Object, versioner storage.Versioner, transformer value.Transformer) *watcher {
|
||||
func newWatcher(client *clientv3.Client, codec runtime.Codec, groupResource schema.GroupResource, newFunc func() runtime.Object, versioner storage.Versioner) *watcher {
|
||||
res := &watcher{
|
||||
client: client,
|
||||
codec: codec,
|
||||
newFunc: newFunc,
|
||||
versioner: versioner,
|
||||
transformer: transformer,
|
||||
client: client,
|
||||
codec: codec,
|
||||
groupResource: groupResource,
|
||||
newFunc: newFunc,
|
||||
versioner: versioner,
|
||||
}
|
||||
if newFunc == nil {
|
||||
res.objectType = "<unknown>"
|
||||
@@ -115,11 +106,11 @@ func newWatcher(client *clientv3.Client, codec runtime.Codec, newFunc func() run
|
||||
// If recursive is false, it watches on given key.
|
||||
// If recursive is true, it watches any children and directories under the key, excluding the root key itself.
|
||||
// pred must be non-nil. Only if pred matches the change, it will be returned.
|
||||
func (w *watcher) Watch(ctx context.Context, key string, rev int64, recursive, progressNotify bool, pred storage.SelectionPredicate) (watch.Interface, error) {
|
||||
func (w *watcher) Watch(ctx context.Context, key string, rev int64, recursive, progressNotify bool, transformer value.Transformer, pred storage.SelectionPredicate) (watch.Interface, error) {
|
||||
if recursive && !strings.HasSuffix(key, "/") {
|
||||
key += "/"
|
||||
}
|
||||
wc := w.createWatchChan(ctx, key, rev, recursive, progressNotify, pred)
|
||||
wc := w.createWatchChan(ctx, key, rev, recursive, progressNotify, transformer, pred)
|
||||
go wc.run()
|
||||
|
||||
// For etcd watch we don't have an easy way to answer whether the watch
|
||||
@@ -132,9 +123,10 @@ func (w *watcher) Watch(ctx context.Context, key string, rev int64, recursive, p
|
||||
return wc, nil
|
||||
}
|
||||
|
||||
func (w *watcher) createWatchChan(ctx context.Context, key string, rev int64, recursive, progressNotify bool, pred storage.SelectionPredicate) *watchChan {
|
||||
func (w *watcher) createWatchChan(ctx context.Context, key string, rev int64, recursive, progressNotify bool, transformer value.Transformer, pred storage.SelectionPredicate) *watchChan {
|
||||
wc := &watchChan{
|
||||
watcher: w,
|
||||
transformer: transformer,
|
||||
key: key,
|
||||
initialRev: rev,
|
||||
recursive: recursive,
|
||||
@@ -259,7 +251,7 @@ func (wc *watchChan) startWatching(watchClosedCh chan struct{}) {
|
||||
}
|
||||
if wres.IsProgressNotify() {
|
||||
wc.sendEvent(progressNotifyEvent(wres.Header.GetRevision()))
|
||||
metrics.RecordEtcdBookmark(wc.watcher.objectType)
|
||||
metrics.RecordEtcdBookmark(wc.watcher.groupResource.String())
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -292,7 +284,7 @@ func (wc *watchChan) processEvent(wg *sync.WaitGroup) {
|
||||
continue
|
||||
}
|
||||
if len(wc.resultChan) == outgoingBufSize {
|
||||
klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow dispatching events to watchers", "outgoingEvents", outgoingBufSize, "objectType", wc.watcher.objectType)
|
||||
klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow dispatching events to watchers", "outgoingEvents", outgoingBufSize, "objectType", wc.watcher.objectType, "groupResource", wc.watcher.groupResource)
|
||||
}
|
||||
// If user couldn't receive results fast enough, we also block incoming events from watcher.
|
||||
// Because storing events in local will cause more memory usage.
|
||||
@@ -411,7 +403,7 @@ func (wc *watchChan) sendError(err error) {
|
||||
|
||||
func (wc *watchChan) sendEvent(e *event) {
|
||||
if len(wc.incomingEventChan) == incomingBufSize {
|
||||
klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow decoding, user not receiving fast, or other processing logic", "incomingEvents", incomingBufSize, "objectType", wc.watcher.objectType)
|
||||
klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow decoding, user not receiving fast, or other processing logic", "incomingEvents", incomingBufSize, "objectType", wc.watcher.objectType, "groupResource", wc.watcher.groupResource)
|
||||
}
|
||||
select {
|
||||
case wc.incomingEventChan <- e:
|
||||
@@ -426,7 +418,7 @@ func (wc *watchChan) prepareObjs(e *event) (curObj runtime.Object, oldObj runtim
|
||||
}
|
||||
|
||||
if !e.isDeleted {
|
||||
data, _, err := wc.watcher.transformer.TransformFromStorage(wc.ctx, e.value, authenticatedDataString(e.key))
|
||||
data, _, err := wc.transformer.TransformFromStorage(wc.ctx, e.value, authenticatedDataString(e.key))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -441,7 +433,7 @@ func (wc *watchChan) prepareObjs(e *event) (curObj runtime.Object, oldObj runtim
|
||||
// we need the object only to compute whether it was filtered out
|
||||
// before).
|
||||
if len(e.prevValue) > 0 && (e.isDeleted || !wc.acceptAll()) {
|
||||
data, _, err := wc.watcher.transformer.TransformFromStorage(wc.ctx, e.prevValue, authenticatedDataString(e.key))
|
||||
data, _, err := wc.transformer.TransformFromStorage(wc.ctx, e.prevValue, authenticatedDataString(e.key))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -459,9 +451,6 @@ func decodeObj(codec runtime.Codec, versioner storage.Versioner, data []byte, re
|
||||
obj, err := runtime.Decode(codec, []byte(data))
|
||||
if err != nil {
|
||||
if fatalOnDecodeError {
|
||||
// catch watch decode error iff we caused it on
|
||||
// purpose during a unit test
|
||||
defer testingDeferOnDecodeError()
|
||||
// we are running in a test environment and thus an
|
||||
// error here is due to a coder mistake if the defer
|
||||
// does not catch it
|
||||
|
||||
2
vendor/k8s.io/apiserver/pkg/storage/names/generate.go
generated
vendored
2
vendor/k8s.io/apiserver/pkg/storage/names/generate.go
generated
vendored
@@ -25,7 +25,7 @@ import (
|
||||
// NameGenerator generates names for objects. Some backends may have more information
|
||||
// available to guide selection of new names and this interface hides those details.
|
||||
type NameGenerator interface {
|
||||
// GenerateName generates a valid name from the base name, adding a random suffix to the
|
||||
// GenerateName generates a valid name from the base name, adding a random suffix to
|
||||
// the base. If base is valid, the returned name must also be valid. The generator is
|
||||
// responsible for knowing the maximum valid name length.
|
||||
GenerateName(base string) string
|
||||
|
||||
56
vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go
generated
vendored
56
vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go
generated
vendored
@@ -35,6 +35,7 @@ import (
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"golang.org/x/time/rate"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -47,7 +48,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/storage/etcd3"
|
||||
"k8s.io/apiserver/pkg/storage/etcd3/metrics"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
"k8s.io/apiserver/pkg/storage/value"
|
||||
"k8s.io/apiserver/pkg/storage/value/encrypt/identity"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-base/metrics/legacyregistry"
|
||||
tracing "k8s.io/component-base/tracing"
|
||||
@@ -123,20 +124,42 @@ func newETCD3ReadyCheck(c storagebackend.Config, stopCh <-chan struct{}) (func()
|
||||
return newETCD3Check(c, timeout, stopCh)
|
||||
}
|
||||
|
||||
// atomic error acts as a cache for atomically store an error
|
||||
// the error is only updated if the timestamp is more recent than
|
||||
// current stored error.
|
||||
type atomicLastError struct {
|
||||
mu sync.RWMutex
|
||||
err error
|
||||
timestamp time.Time
|
||||
}
|
||||
|
||||
func (a *atomicLastError) Store(err error, t time.Time) {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
if a.timestamp.IsZero() || a.timestamp.Before(t) {
|
||||
a.err = err
|
||||
a.timestamp = t
|
||||
}
|
||||
}
|
||||
|
||||
func (a *atomicLastError) Load() error {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return a.err
|
||||
}
|
||||
|
||||
func newETCD3Check(c storagebackend.Config, timeout time.Duration, stopCh <-chan struct{}) (func() error, error) {
|
||||
// constructing the etcd v3 client blocks and times out if etcd is not available.
|
||||
// retry in a loop in the background until we successfully create the client, storing the client or error encountered
|
||||
|
||||
lock := sync.Mutex{}
|
||||
lock := sync.RWMutex{}
|
||||
var client *clientv3.Client
|
||||
clientErr := fmt.Errorf("etcd client connection not yet established")
|
||||
|
||||
go wait.PollUntil(time.Second, func() (bool, error) {
|
||||
newClient, err := newETCD3Client(c.Transport)
|
||||
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
// Ensure that server is already not shutting down.
|
||||
select {
|
||||
case <-stopCh:
|
||||
@@ -146,7 +169,6 @@ func newETCD3Check(c storagebackend.Config, timeout time.Duration, stopCh <-chan
|
||||
return true, nil
|
||||
default:
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
clientErr = err
|
||||
return false, nil
|
||||
@@ -169,25 +191,37 @@ func newETCD3Check(c storagebackend.Config, timeout time.Duration, stopCh <-chan
|
||||
}
|
||||
}()
|
||||
|
||||
// limit to a request every half of the configured timeout with a maximum burst of one
|
||||
// rate limited requests will receive the last request sent error (note: not the last received response)
|
||||
limiter := rate.NewLimiter(rate.Every(timeout/2), 1)
|
||||
// initial state is the clientErr
|
||||
lastError := &atomicLastError{err: fmt.Errorf("etcd client connection not yet established")}
|
||||
|
||||
return func() error {
|
||||
// Given that client is closed on shutdown we hold the lock for
|
||||
// the entire period of healthcheck call to ensure that client will
|
||||
// not be closed during healthcheck.
|
||||
// Given that healthchecks has a 2s timeout, worst case of blocking
|
||||
// shutdown for additional 2s seems acceptable.
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
lock.RLock()
|
||||
defer lock.RUnlock()
|
||||
|
||||
if clientErr != nil {
|
||||
return clientErr
|
||||
}
|
||||
if limiter.Allow() == false {
|
||||
return lastError.Load()
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
// See https://github.com/etcd-io/etcd/blob/c57f8b3af865d1b531b979889c602ba14377420e/etcdctl/ctlv3/command/ep_command.go#L118
|
||||
now := time.Now()
|
||||
_, err := client.Get(ctx, path.Join("/", c.Prefix, "health"))
|
||||
if err == nil {
|
||||
return nil
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting data from etcd: %w", err)
|
||||
}
|
||||
return fmt.Errorf("error getting data from etcd: %w", err)
|
||||
lastError.Store(err, now)
|
||||
return err
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -361,7 +395,7 @@ func newETCD3Storage(c storagebackend.ConfigForResource, newFunc func() runtime.
|
||||
}
|
||||
transformer := c.Transformer
|
||||
if transformer == nil {
|
||||
transformer = value.IdentityTransformer
|
||||
transformer = identity.NewEncryptCheckTransformer()
|
||||
}
|
||||
return etcd3.New(client, c.Codec, newFunc, c.Prefix, c.GroupResource, transformer, c.Paging, c.LeaseManagerConfig), destroyFunc, nil
|
||||
}
|
||||
|
||||
8
vendor/k8s.io/apiserver/pkg/storage/value/OWNERS
generated
vendored
Normal file
8
vendor/k8s.io/apiserver/pkg/storage/value/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- sig-auth-encryption-at-rest-approvers
|
||||
reviewers:
|
||||
- sig-auth-encryption-at-rest-reviewers
|
||||
labels:
|
||||
- sig/auth
|
||||
4
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go
generated
vendored
4
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go
generated
vendored
@@ -63,7 +63,7 @@ type envelopeTransformer struct {
|
||||
// It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to
|
||||
// the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently
|
||||
// used decrypted DEKs in memory.
|
||||
func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) (value.Transformer, error) {
|
||||
func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer {
|
||||
var (
|
||||
cache *lru.Cache
|
||||
)
|
||||
@@ -77,7 +77,7 @@ func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransfor
|
||||
baseTransformerFunc: baseTransformerFunc,
|
||||
cacheEnabled: cacheSize > 0,
|
||||
cacheSize: cacheSize,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption.
|
||||
|
||||
16
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go
generated
vendored
16
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go
generated
vendored
@@ -24,13 +24,13 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util"
|
||||
kmsapi "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1"
|
||||
"k8s.io/klog/v2"
|
||||
kmsapi "k8s.io/kms/apis/v1beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -52,7 +52,7 @@ type gRPCService struct {
|
||||
}
|
||||
|
||||
// NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider.
|
||||
func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error) {
|
||||
func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) {
|
||||
klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint)
|
||||
|
||||
addr, err := util.ParseEndpoint(endpoint)
|
||||
@@ -84,6 +84,14 @@ func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error)
|
||||
}
|
||||
|
||||
s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection)
|
||||
|
||||
go func() {
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
<-ctx.Done()
|
||||
_ = s.connection.Close()
|
||||
}()
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
||||
95
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go
generated
vendored
95
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go
generated
vendored
@@ -27,16 +27,26 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/apiserver/pkg/storage/value"
|
||||
kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1"
|
||||
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/lru"
|
||||
)
|
||||
|
||||
const (
|
||||
// KMSAPIVersion is the version of the KMS API.
|
||||
KMSAPIVersion = "v2alpha1"
|
||||
// annotationsMaxSize is the maximum size of the annotations.
|
||||
annotationsMaxSize = 32 * 1024 // 32 kB
|
||||
// keyIDMaxSize is the maximum size of the keyID.
|
||||
keyIDMaxSize = 1 * 1024 // 1 kB
|
||||
// encryptedDEKMaxSize is the maximum size of the encrypted DEK.
|
||||
encryptedDEKMaxSize = 1 * 1024 // 1 kB
|
||||
)
|
||||
|
||||
// Service allows encrypting and decrypting data using an external Key Management Service.
|
||||
@@ -60,8 +70,6 @@ type envelopeTransformer struct {
|
||||
|
||||
cacheSize int
|
||||
cacheEnabled bool
|
||||
|
||||
pluginName string
|
||||
}
|
||||
|
||||
// EncryptResponse is the response from the Envelope service when encrypting data.
|
||||
@@ -89,7 +97,7 @@ type StatusResponse struct {
|
||||
// It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to
|
||||
// the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently
|
||||
// used decrypted DEKs in memory.
|
||||
func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) (value.Transformer, error) {
|
||||
func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer {
|
||||
var cache *lru.Cache
|
||||
|
||||
if cacheSize > 0 {
|
||||
@@ -104,7 +112,7 @@ func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransfor
|
||||
baseTransformerFunc: baseTransformerFunc,
|
||||
cacheEnabled: cacheSize > 0,
|
||||
cacheSize: cacheSize,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption.
|
||||
@@ -124,6 +132,7 @@ func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []b
|
||||
value.RecordCacheMiss()
|
||||
}
|
||||
uid := string(uuid.NewUUID())
|
||||
klog.V(6).InfoS("Decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData()))
|
||||
key, err := t.envelopeService.Decrypt(ctx, uid, &DecryptRequest{
|
||||
Ciphertext: encryptedObject.EncryptedDEK,
|
||||
KeyID: encryptedObject.KeyID,
|
||||
@@ -151,6 +160,7 @@ func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byt
|
||||
}
|
||||
|
||||
uid := string(uuid.NewUUID())
|
||||
klog.V(6).InfoS("Encrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData()))
|
||||
resp, err := t.envelopeService.Encrypt(ctx, uid, newKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encrypt DEK, error: %w", err)
|
||||
@@ -208,6 +218,9 @@ func (t *envelopeTransformer) getTransformer(encKey []byte) value.Transformer {
|
||||
|
||||
// doEncode encodes the EncryptedObject to a byte array.
|
||||
func (t *envelopeTransformer) doEncode(request *kmstypes.EncryptedObject) ([]byte, error) {
|
||||
if err := validateEncryptedObject(request); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Marshal(request)
|
||||
}
|
||||
|
||||
@@ -217,16 +230,9 @@ func (t *envelopeTransformer) doDecode(originalData []byte) (*kmstypes.Encrypted
|
||||
if err := proto.Unmarshal(originalData, o); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate the EncryptedObject
|
||||
if o.EncryptedData == nil {
|
||||
return nil, fmt.Errorf("encrypted data is nil after unmarshal")
|
||||
}
|
||||
if o.KeyID == "" {
|
||||
return nil, fmt.Errorf("keyID is empty after unmarshal")
|
||||
}
|
||||
if o.EncryptedDEK == nil {
|
||||
return nil, fmt.Errorf("encrypted dek is nil after unmarshal")
|
||||
if err := validateEncryptedObject(o); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return o, nil
|
||||
@@ -244,3 +250,66 @@ func generateKey(length int) (key []byte, err error) {
|
||||
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func validateEncryptedObject(o *kmstypes.EncryptedObject) error {
|
||||
if o == nil {
|
||||
return fmt.Errorf("encrypted object is nil")
|
||||
}
|
||||
if len(o.EncryptedData) == 0 {
|
||||
return fmt.Errorf("encrypted data is empty")
|
||||
}
|
||||
if err := validateEncryptedDEK(o.EncryptedDEK); err != nil {
|
||||
return fmt.Errorf("failed to validate encrypted DEK: %w", err)
|
||||
}
|
||||
if err := validateKeyID(o.KeyID); err != nil {
|
||||
return fmt.Errorf("failed to validate key id: %w", err)
|
||||
}
|
||||
if err := validateAnnotations(o.Annotations); err != nil {
|
||||
return fmt.Errorf("failed to validate annotations: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateEncryptedDEK tests the following:
|
||||
// 1. The encrypted DEK is not empty.
|
||||
// 2. The size of encrypted DEK is less than 1 kB.
|
||||
func validateEncryptedDEK(encryptedDEK []byte) error {
|
||||
if len(encryptedDEK) == 0 {
|
||||
return fmt.Errorf("encrypted DEK is empty")
|
||||
}
|
||||
if len(encryptedDEK) > encryptedDEKMaxSize {
|
||||
return fmt.Errorf("encrypted DEK is %d bytes, which exceeds the max size of %d", len(encryptedDEK), encryptedDEKMaxSize)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateAnnotations tests the following:
|
||||
// 1. checks if the annotation key is fully qualified
|
||||
// 2. The size of annotations keys + values is less than 32 kB.
|
||||
func validateAnnotations(annotations map[string][]byte) error {
|
||||
var errs []error
|
||||
var totalSize uint64
|
||||
for k, v := range annotations {
|
||||
if fieldErr := validation.IsFullyQualifiedDomainName(field.NewPath("annotations"), k); fieldErr != nil {
|
||||
errs = append(errs, fieldErr.ToAggregate())
|
||||
}
|
||||
totalSize += uint64(len(k)) + uint64(len(v))
|
||||
}
|
||||
if totalSize > annotationsMaxSize {
|
||||
errs = append(errs, fmt.Errorf("total size of annotations is %d, which exceeds the max size of %d", totalSize, annotationsMaxSize))
|
||||
}
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// validateKeyID tests the following:
|
||||
// 1. The keyID is not empty.
|
||||
// 2. The size of keyID is less than 1 kB.
|
||||
func validateKeyID(keyID string) error {
|
||||
if len(keyID) == 0 {
|
||||
return fmt.Errorf("keyID is empty")
|
||||
}
|
||||
if len(keyID) > keyIDMaxSize {
|
||||
return fmt.Errorf("keyID is %d bytes, which exceeds the max size of %d", len(keyID), keyIDMaxSize)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
19
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go
generated
vendored
19
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go
generated
vendored
@@ -23,12 +23,13 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util"
|
||||
kmsapi "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1"
|
||||
"k8s.io/klog/v2"
|
||||
kmsapi "k8s.io/kms/apis/v2alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -44,7 +45,7 @@ type gRPCService struct {
|
||||
}
|
||||
|
||||
// NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider.
|
||||
func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error) {
|
||||
func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) {
|
||||
klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint)
|
||||
|
||||
addr, err := util.ParseEndpoint(endpoint)
|
||||
@@ -55,7 +56,7 @@ func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error)
|
||||
s := &gRPCService{callTimeout: callTimeout}
|
||||
s.connection, err = grpc.Dial(
|
||||
addr,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
|
||||
grpc.WithContextDialer(
|
||||
func(context.Context, string) (net.Conn, error) {
|
||||
@@ -75,6 +76,14 @@ func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error)
|
||||
}
|
||||
|
||||
s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection)
|
||||
|
||||
go func() {
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
<-ctx.Done()
|
||||
_ = s.connection.Close()
|
||||
}()
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
||||
502
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/api.pb.go
generated
vendored
502
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/api.pb.go
generated
vendored
@@ -1,502 +0,0 @@
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: api.proto
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type VersionRequest struct {
|
||||
// Version of the KMS plugin API.
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *VersionRequest) Reset() { *m = VersionRequest{} }
|
||||
func (m *VersionRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*VersionRequest) ProtoMessage() {}
|
||||
func (*VersionRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{0}
|
||||
}
|
||||
func (m *VersionRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_VersionRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *VersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_VersionRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *VersionRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_VersionRequest.Merge(m, src)
|
||||
}
|
||||
func (m *VersionRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_VersionRequest.Size(m)
|
||||
}
|
||||
func (m *VersionRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_VersionRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_VersionRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *VersionRequest) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type VersionResponse struct {
|
||||
// Version of the KMS plugin API.
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// Name of the KMS provider.
|
||||
RuntimeName string `protobuf:"bytes,2,opt,name=runtime_name,json=runtimeName,proto3" json:"runtime_name,omitempty"`
|
||||
// Version of the KMS provider. The string must be semver-compatible.
|
||||
RuntimeVersion string `protobuf:"bytes,3,opt,name=runtime_version,json=runtimeVersion,proto3" json:"runtime_version,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *VersionResponse) Reset() { *m = VersionResponse{} }
|
||||
func (m *VersionResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*VersionResponse) ProtoMessage() {}
|
||||
func (*VersionResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{1}
|
||||
}
|
||||
func (m *VersionResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_VersionResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *VersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_VersionResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *VersionResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_VersionResponse.Merge(m, src)
|
||||
}
|
||||
func (m *VersionResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_VersionResponse.Size(m)
|
||||
}
|
||||
func (m *VersionResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_VersionResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_VersionResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *VersionResponse) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *VersionResponse) GetRuntimeName() string {
|
||||
if m != nil {
|
||||
return m.RuntimeName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *VersionResponse) GetRuntimeVersion() string {
|
||||
if m != nil {
|
||||
return m.RuntimeVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DecryptRequest struct {
|
||||
// Version of the KMS plugin API.
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// The data to be decrypted.
|
||||
Cipher []byte `protobuf:"bytes,2,opt,name=cipher,proto3" json:"cipher,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DecryptRequest) Reset() { *m = DecryptRequest{} }
|
||||
func (m *DecryptRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*DecryptRequest) ProtoMessage() {}
|
||||
func (*DecryptRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{2}
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_DecryptRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_DecryptRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_DecryptRequest.Merge(m, src)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_DecryptRequest.Size(m)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_DecryptRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_DecryptRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *DecryptRequest) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DecryptRequest) GetCipher() []byte {
|
||||
if m != nil {
|
||||
return m.Cipher
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DecryptResponse struct {
|
||||
// The decrypted data.
|
||||
Plain []byte `protobuf:"bytes,1,opt,name=plain,proto3" json:"plain,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DecryptResponse) Reset() { *m = DecryptResponse{} }
|
||||
func (m *DecryptResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*DecryptResponse) ProtoMessage() {}
|
||||
func (*DecryptResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{3}
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_DecryptResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_DecryptResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_DecryptResponse.Merge(m, src)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_DecryptResponse.Size(m)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_DecryptResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_DecryptResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *DecryptResponse) GetPlain() []byte {
|
||||
if m != nil {
|
||||
return m.Plain
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EncryptRequest struct {
|
||||
// Version of the KMS plugin API.
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// The data to be encrypted.
|
||||
Plain []byte `protobuf:"bytes,2,opt,name=plain,proto3" json:"plain,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EncryptRequest) Reset() { *m = EncryptRequest{} }
|
||||
func (m *EncryptRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*EncryptRequest) ProtoMessage() {}
|
||||
func (*EncryptRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{4}
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EncryptRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EncryptRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EncryptRequest.Merge(m, src)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_EncryptRequest.Size(m)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EncryptRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EncryptRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *EncryptRequest) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *EncryptRequest) GetPlain() []byte {
|
||||
if m != nil {
|
||||
return m.Plain
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EncryptResponse struct {
|
||||
// The encrypted data.
|
||||
Cipher []byte `protobuf:"bytes,1,opt,name=cipher,proto3" json:"cipher,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EncryptResponse) Reset() { *m = EncryptResponse{} }
|
||||
func (m *EncryptResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*EncryptResponse) ProtoMessage() {}
|
||||
func (*EncryptResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{5}
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EncryptResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EncryptResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EncryptResponse.Merge(m, src)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_EncryptResponse.Size(m)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EncryptResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EncryptResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *EncryptResponse) GetCipher() []byte {
|
||||
if m != nil {
|
||||
return m.Cipher
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*VersionRequest)(nil), "v1beta1.VersionRequest")
|
||||
proto.RegisterType((*VersionResponse)(nil), "v1beta1.VersionResponse")
|
||||
proto.RegisterType((*DecryptRequest)(nil), "v1beta1.DecryptRequest")
|
||||
proto.RegisterType((*DecryptResponse)(nil), "v1beta1.DecryptResponse")
|
||||
proto.RegisterType((*EncryptRequest)(nil), "v1beta1.EncryptRequest")
|
||||
proto.RegisterType((*EncryptResponse)(nil), "v1beta1.EncryptResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) }
|
||||
|
||||
var fileDescriptor_00212fb1f9d3bf1c = []byte{
|
||||
// 286 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x4b, 0xc3, 0x30,
|
||||
0x14, 0x5f, 0x27, 0xae, 0xec, 0x59, 0x5a, 0x08, 0x43, 0x8b, 0x27, 0xcd, 0x65, 0xea, 0xa1, 0x30,
|
||||
0xbd, 0x8b, 0x88, 0x9e, 0x44, 0x0f, 0x15, 0xbc, 0x4a, 0x56, 0x1e, 0x1a, 0xb0, 0x69, 0x4c, 0xb3,
|
||||
0xca, 0xbe, 0xa8, 0x9f, 0x47, 0x6c, 0x5e, 0x6b, 0x3a, 0x11, 0x77, 0x7c, 0x2f, 0xef, 0xf7, 0xef,
|
||||
0xbd, 0xc0, 0x54, 0x68, 0x99, 0x69, 0x53, 0xd9, 0x8a, 0x85, 0xcd, 0x62, 0x89, 0x56, 0x2c, 0xf8,
|
||||
0x19, 0xc4, 0x4f, 0x68, 0x6a, 0x59, 0xa9, 0x1c, 0xdf, 0x57, 0x58, 0x5b, 0x96, 0x42, 0xd8, 0xb8,
|
||||
0x4e, 0x1a, 0x1c, 0x05, 0x27, 0xd3, 0xbc, 0x2b, 0xf9, 0x07, 0x24, 0xfd, 0x6c, 0xad, 0x2b, 0x55,
|
||||
0xe3, 0xdf, 0xc3, 0xec, 0x18, 0x22, 0xb3, 0x52, 0x56, 0x96, 0xf8, 0xac, 0x44, 0x89, 0xe9, 0xb8,
|
||||
0x7d, 0xde, 0xa3, 0xde, 0x83, 0x28, 0x91, 0xcd, 0x21, 0xe9, 0x46, 0x3a, 0x92, 0x9d, 0x76, 0x2a,
|
||||
0xa6, 0x36, 0xa9, 0xf1, 0x6b, 0x88, 0x6f, 0xb0, 0x30, 0x6b, 0x6d, 0xff, 0x35, 0xc9, 0xf6, 0x61,
|
||||
0x52, 0x48, 0xfd, 0x8a, 0xa6, 0x55, 0x8c, 0x72, 0xaa, 0xf8, 0x1c, 0x92, 0x9e, 0x83, 0xcc, 0xcf,
|
||||
0x60, 0x57, 0xbf, 0x09, 0xe9, 0x28, 0xa2, 0xdc, 0x15, 0xfc, 0x0a, 0xe2, 0x5b, 0xb5, 0xa5, 0x58,
|
||||
0xcf, 0x30, 0xf6, 0x19, 0x4e, 0x21, 0xe9, 0x19, 0x48, 0xea, 0xc7, 0x55, 0xe0, 0xbb, 0x3a, 0xff,
|
||||
0x0c, 0x60, 0x76, 0x87, 0xeb, 0x7b, 0xa1, 0xc4, 0x0b, 0x96, 0xa8, 0xec, 0x23, 0x9a, 0x46, 0x16,
|
||||
0xc8, 0x2e, 0x21, 0xa4, 0xf4, 0xec, 0x20, 0xa3, 0x63, 0x65, 0xc3, 0x4b, 0x1d, 0xa6, 0xbf, 0x1f,
|
||||
0x9c, 0x1c, 0x1f, 0x7d, 0xe3, 0x29, 0xae, 0x87, 0x1f, 0x2e, 0xd1, 0xc3, 0x6f, 0x6c, 0xc6, 0xe1,
|
||||
0x29, 0x83, 0x87, 0x1f, 0xee, 0xc5, 0xc3, 0x6f, 0xc4, 0xe5, 0xa3, 0xe5, 0xa4, 0xfd, 0x67, 0x17,
|
||||
0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x57, 0xc8, 0x65, 0x5a, 0x74, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// KeyManagementServiceClient is the client API for KeyManagementService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type KeyManagementServiceClient interface {
|
||||
// Version returns the runtime name and runtime version of the KMS provider.
|
||||
Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error)
|
||||
// Execute decryption operation in KMS provider.
|
||||
Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error)
|
||||
// Execute encryption operation in KMS provider.
|
||||
Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error)
|
||||
}
|
||||
|
||||
type keyManagementServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClient {
|
||||
return &keyManagementServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *keyManagementServiceClient) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) {
|
||||
out := new(VersionResponse)
|
||||
err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Version", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) {
|
||||
out := new(DecryptResponse)
|
||||
err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Decrypt", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) {
|
||||
out := new(EncryptResponse)
|
||||
err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Encrypt", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// KeyManagementServiceServer is the server API for KeyManagementService service.
|
||||
type KeyManagementServiceServer interface {
|
||||
// Version returns the runtime name and runtime version of the KMS provider.
|
||||
Version(context.Context, *VersionRequest) (*VersionResponse, error)
|
||||
// Execute decryption operation in KMS provider.
|
||||
Decrypt(context.Context, *DecryptRequest) (*DecryptResponse, error)
|
||||
// Execute encryption operation in KMS provider.
|
||||
Encrypt(context.Context, *EncryptRequest) (*EncryptResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedKeyManagementServiceServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedKeyManagementServiceServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedKeyManagementServiceServer) Version(ctx context.Context, req *VersionRequest) (*VersionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Version not implemented")
|
||||
}
|
||||
func (*UnimplementedKeyManagementServiceServer) Decrypt(ctx context.Context, req *DecryptRequest) (*DecryptResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Decrypt not implemented")
|
||||
}
|
||||
func (*UnimplementedKeyManagementServiceServer) Encrypt(ctx context.Context, req *EncryptRequest) (*EncryptResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Encrypt not implemented")
|
||||
}
|
||||
|
||||
func RegisterKeyManagementServiceServer(s *grpc.Server, srv KeyManagementServiceServer) {
|
||||
s.RegisterService(&_KeyManagementService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _KeyManagementService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(VersionRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KeyManagementServiceServer).Version(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/v1beta1.KeyManagementService/Version",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KeyManagementServiceServer).Version(ctx, req.(*VersionRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DecryptRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KeyManagementServiceServer).Decrypt(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/v1beta1.KeyManagementService/Decrypt",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(EncryptRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KeyManagementServiceServer).Encrypt(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/v1beta1.KeyManagementService/Encrypt",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _KeyManagementService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "v1beta1.KeyManagementService",
|
||||
HandlerType: (*KeyManagementServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Version",
|
||||
Handler: _KeyManagementService_Version_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Decrypt",
|
||||
Handler: _KeyManagementService_Decrypt_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Encrypt",
|
||||
Handler: _KeyManagementService_Encrypt_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api.proto",
|
||||
}
|
||||
70
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/api.proto
generated
vendored
70
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/api.proto
generated
vendored
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
// To regenerate api.pb.go run hack/update-generated-kms.sh
|
||||
syntax = "proto3";
|
||||
|
||||
package v1beta1;
|
||||
|
||||
// This service defines the public APIs for remote KMS provider.
|
||||
service KeyManagementService {
|
||||
// Version returns the runtime name and runtime version of the KMS provider.
|
||||
rpc Version(VersionRequest) returns (VersionResponse) {}
|
||||
|
||||
// Execute decryption operation in KMS provider.
|
||||
rpc Decrypt(DecryptRequest) returns (DecryptResponse) {}
|
||||
// Execute encryption operation in KMS provider.
|
||||
rpc Encrypt(EncryptRequest) returns (EncryptResponse) {}
|
||||
}
|
||||
|
||||
message VersionRequest {
|
||||
// Version of the KMS plugin API.
|
||||
string version = 1;
|
||||
}
|
||||
|
||||
message VersionResponse {
|
||||
// Version of the KMS plugin API.
|
||||
string version = 1;
|
||||
// Name of the KMS provider.
|
||||
string runtime_name = 2;
|
||||
// Version of the KMS provider. The string must be semver-compatible.
|
||||
string runtime_version = 3;
|
||||
}
|
||||
|
||||
message DecryptRequest {
|
||||
// Version of the KMS plugin API.
|
||||
string version = 1;
|
||||
// The data to be decrypted.
|
||||
bytes cipher = 2;
|
||||
}
|
||||
|
||||
message DecryptResponse {
|
||||
// The decrypted data.
|
||||
bytes plain = 1;
|
||||
}
|
||||
|
||||
message EncryptRequest {
|
||||
// Version of the KMS plugin API.
|
||||
string version = 1;
|
||||
// The data to be encrypted.
|
||||
bytes plain = 2;
|
||||
}
|
||||
|
||||
message EncryptResponse {
|
||||
// The encrypted data.
|
||||
bytes cipher = 1;
|
||||
}
|
||||
|
||||
23
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/v1beta1.go
generated
vendored
23
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/v1beta1.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 v1beta1 contains definition of kms-plugin's gRPC service.
|
||||
package v1beta1
|
||||
|
||||
// IsVersionCheckMethod determines whether the supplied method is a version check against kms-plugin.
|
||||
func IsVersionCheckMethod(method string) bool {
|
||||
return method == "/v1beta1.KeyManagementService/Version"
|
||||
}
|
||||
542
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1/api.pb.go
generated
vendored
542
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1/api.pb.go
generated
vendored
@@ -1,542 +0,0 @@
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: api.proto
|
||||
|
||||
package v2alpha1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type StatusRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *StatusRequest) Reset() { *m = StatusRequest{} }
|
||||
func (m *StatusRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatusRequest) ProtoMessage() {}
|
||||
func (*StatusRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{0}
|
||||
}
|
||||
func (m *StatusRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_StatusRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *StatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_StatusRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *StatusRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_StatusRequest.Merge(m, src)
|
||||
}
|
||||
func (m *StatusRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_StatusRequest.Size(m)
|
||||
}
|
||||
func (m *StatusRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_StatusRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_StatusRequest proto.InternalMessageInfo
|
||||
|
||||
type StatusResponse struct {
|
||||
// Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message.
|
||||
Healthz string `protobuf:"bytes,2,opt,name=healthz,proto3" json:"healthz,omitempty"`
|
||||
// the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage.
|
||||
KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *StatusResponse) Reset() { *m = StatusResponse{} }
|
||||
func (m *StatusResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatusResponse) ProtoMessage() {}
|
||||
func (*StatusResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{1}
|
||||
}
|
||||
func (m *StatusResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_StatusResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *StatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_StatusResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *StatusResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_StatusResponse.Merge(m, src)
|
||||
}
|
||||
func (m *StatusResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_StatusResponse.Size(m)
|
||||
}
|
||||
func (m *StatusResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_StatusResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_StatusResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *StatusResponse) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *StatusResponse) GetHealthz() string {
|
||||
if m != nil {
|
||||
return m.Healthz
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *StatusResponse) GetKeyId() string {
|
||||
if m != nil {
|
||||
return m.KeyId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DecryptRequest struct {
|
||||
// The data to be decrypted.
|
||||
Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"`
|
||||
// UID is a unique identifier for the request.
|
||||
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
|
||||
// The keyID that was provided to the apiserver during encryption.
|
||||
// This represents the KMS KEK that was used to encrypt the data.
|
||||
KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
|
||||
// Additional metadata that was sent by the KMS plugin during encryption.
|
||||
Annotations map[string][]byte `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DecryptRequest) Reset() { *m = DecryptRequest{} }
|
||||
func (m *DecryptRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*DecryptRequest) ProtoMessage() {}
|
||||
func (*DecryptRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{2}
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_DecryptRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_DecryptRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_DecryptRequest.Merge(m, src)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_DecryptRequest.Size(m)
|
||||
}
|
||||
func (m *DecryptRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_DecryptRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_DecryptRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *DecryptRequest) GetCiphertext() []byte {
|
||||
if m != nil {
|
||||
return m.Ciphertext
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DecryptRequest) GetUid() string {
|
||||
if m != nil {
|
||||
return m.Uid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DecryptRequest) GetKeyId() string {
|
||||
if m != nil {
|
||||
return m.KeyId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DecryptRequest) GetAnnotations() map[string][]byte {
|
||||
if m != nil {
|
||||
return m.Annotations
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DecryptResponse struct {
|
||||
// The decrypted data.
|
||||
Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DecryptResponse) Reset() { *m = DecryptResponse{} }
|
||||
func (m *DecryptResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*DecryptResponse) ProtoMessage() {}
|
||||
func (*DecryptResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{3}
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_DecryptResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_DecryptResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_DecryptResponse.Merge(m, src)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_DecryptResponse.Size(m)
|
||||
}
|
||||
func (m *DecryptResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_DecryptResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_DecryptResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *DecryptResponse) GetPlaintext() []byte {
|
||||
if m != nil {
|
||||
return m.Plaintext
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EncryptRequest struct {
|
||||
// The data to be encrypted.
|
||||
Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"`
|
||||
// UID is a unique identifier for the request.
|
||||
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EncryptRequest) Reset() { *m = EncryptRequest{} }
|
||||
func (m *EncryptRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*EncryptRequest) ProtoMessage() {}
|
||||
func (*EncryptRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{4}
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EncryptRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EncryptRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EncryptRequest.Merge(m, src)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_EncryptRequest.Size(m)
|
||||
}
|
||||
func (m *EncryptRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EncryptRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EncryptRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *EncryptRequest) GetPlaintext() []byte {
|
||||
if m != nil {
|
||||
return m.Plaintext
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptRequest) GetUid() string {
|
||||
if m != nil {
|
||||
return m.Uid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type EncryptResponse struct {
|
||||
// The encrypted data.
|
||||
Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"`
|
||||
// The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use.
|
||||
// This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage.
|
||||
KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
|
||||
// Additional metadata to be stored with the encrypted data.
|
||||
// This metadata can contain the encrypted local KEK that was used to encrypt the DEK.
|
||||
// This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data.
|
||||
Annotations map[string][]byte `protobuf:"bytes,3,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EncryptResponse) Reset() { *m = EncryptResponse{} }
|
||||
func (m *EncryptResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*EncryptResponse) ProtoMessage() {}
|
||||
func (*EncryptResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_00212fb1f9d3bf1c, []int{5}
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EncryptResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EncryptResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EncryptResponse.Merge(m, src)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_EncryptResponse.Size(m)
|
||||
}
|
||||
func (m *EncryptResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EncryptResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EncryptResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *EncryptResponse) GetCiphertext() []byte {
|
||||
if m != nil {
|
||||
return m.Ciphertext
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EncryptResponse) GetKeyId() string {
|
||||
if m != nil {
|
||||
return m.KeyId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *EncryptResponse) GetAnnotations() map[string][]byte {
|
||||
if m != nil {
|
||||
return m.Annotations
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*StatusRequest)(nil), "v2alpha1.StatusRequest")
|
||||
proto.RegisterType((*StatusResponse)(nil), "v2alpha1.StatusResponse")
|
||||
proto.RegisterType((*DecryptRequest)(nil), "v2alpha1.DecryptRequest")
|
||||
proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.DecryptRequest.AnnotationsEntry")
|
||||
proto.RegisterType((*DecryptResponse)(nil), "v2alpha1.DecryptResponse")
|
||||
proto.RegisterType((*EncryptRequest)(nil), "v2alpha1.EncryptRequest")
|
||||
proto.RegisterType((*EncryptResponse)(nil), "v2alpha1.EncryptResponse")
|
||||
proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.EncryptResponse.AnnotationsEntry")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) }
|
||||
|
||||
var fileDescriptor_00212fb1f9d3bf1c = []byte{
|
||||
// 391 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xcf, 0x4f, 0xe2, 0x40,
|
||||
0x14, 0xc7, 0x29, 0x5d, 0x60, 0x79, 0xb0, 0x40, 0x26, 0x6c, 0xb6, 0x4b, 0x36, 0x1b, 0x32, 0x27,
|
||||
0x76, 0x0f, 0xdd, 0x2c, 0x5e, 0x8c, 0x89, 0x06, 0x13, 0x39, 0x18, 0xf4, 0x52, 0x8e, 0x1e, 0xcc,
|
||||
0x08, 0x2f, 0x76, 0x42, 0x9d, 0xd6, 0x76, 0xda, 0x58, 0xff, 0x50, 0x13, 0xff, 0x01, 0xff, 0x0e,
|
||||
0xd3, 0x76, 0xa0, 0x2d, 0x88, 0x9e, 0xbc, 0xcd, 0xfb, 0xd1, 0xef, 0xf7, 0xcd, 0x67, 0x5e, 0xa1,
|
||||
0xc9, 0x3c, 0x6e, 0x7a, 0xbe, 0x2b, 0x5d, 0xf2, 0x35, 0x1a, 0x33, 0xc7, 0xb3, 0xd9, 0x7f, 0xda,
|
||||
0x85, 0x6f, 0x73, 0xc9, 0x64, 0x18, 0x58, 0x78, 0x1f, 0x62, 0x20, 0xe9, 0x15, 0x74, 0xd6, 0x89,
|
||||
0xc0, 0x73, 0x45, 0x80, 0xc4, 0x80, 0x46, 0x84, 0x7e, 0xc0, 0x5d, 0x61, 0x68, 0x43, 0x6d, 0xd4,
|
||||
0xb4, 0xd6, 0x61, 0x52, 0xb1, 0x91, 0x39, 0xd2, 0x7e, 0x34, 0xaa, 0x59, 0x45, 0x85, 0xe4, 0x3b,
|
||||
0xd4, 0x57, 0x18, 0x5f, 0xf3, 0xa5, 0xa1, 0xa7, 0x85, 0xda, 0x0a, 0xe3, 0xf3, 0x25, 0x7d, 0xd1,
|
||||
0xa0, 0x73, 0x86, 0x0b, 0x3f, 0xf6, 0xa4, 0xf2, 0x23, 0xbf, 0x01, 0x16, 0xdc, 0xb3, 0xd1, 0x97,
|
||||
0xf8, 0x20, 0x53, 0x83, 0xb6, 0x55, 0xc8, 0x90, 0x1e, 0xe8, 0x21, 0x5f, 0x2a, 0xfd, 0xe4, 0xb8,
|
||||
0x47, 0x9b, 0xcc, 0xa0, 0xc5, 0x84, 0x70, 0x25, 0x93, 0xdc, 0x15, 0x81, 0xf1, 0x65, 0xa8, 0x8f,
|
||||
0x5a, 0xe3, 0x3f, 0xe6, 0xfa, 0xa6, 0x66, 0xd9, 0xd7, 0x3c, 0xcd, 0x7b, 0xa7, 0x42, 0xfa, 0xb1,
|
||||
0x55, 0xfc, 0x7a, 0x70, 0x02, 0xbd, 0xed, 0x86, 0x64, 0x92, 0x15, 0xc6, 0x8a, 0x41, 0x72, 0x24,
|
||||
0x7d, 0xa8, 0x45, 0xcc, 0x09, 0x31, 0x9d, 0xae, 0x6d, 0x65, 0xc1, 0x51, 0xf5, 0x50, 0xa3, 0xff,
|
||||
0xa0, 0xbb, 0xf1, 0x53, 0x18, 0x7f, 0x41, 0xd3, 0x73, 0x18, 0x17, 0x85, 0x7b, 0xe6, 0x09, 0x3a,
|
||||
0x81, 0xce, 0x54, 0x94, 0xc0, 0xbc, 0xdb, 0xbf, 0x8b, 0x85, 0x3e, 0x69, 0xd0, 0xdd, 0x48, 0x28,
|
||||
0xcf, 0x8f, 0xe0, 0xe6, 0x28, 0xab, 0x45, 0x94, 0x17, 0x65, 0x94, 0x7a, 0x8a, 0xf2, 0x6f, 0x8e,
|
||||
0x72, 0xcb, 0xe6, 0x73, 0x59, 0x8e, 0x9f, 0x35, 0xe8, 0xcf, 0x30, 0xbe, 0x64, 0x82, 0xdd, 0xe2,
|
||||
0x1d, 0x0a, 0x39, 0x47, 0x3f, 0xe2, 0x0b, 0x24, 0xc7, 0x50, 0xcf, 0x56, 0x95, 0xfc, 0xc8, 0x67,
|
||||
0x2b, 0x6d, 0xf3, 0xc0, 0xd8, 0x2d, 0x64, 0x33, 0xd3, 0x0a, 0x99, 0x40, 0x43, 0xbd, 0x11, 0x31,
|
||||
0xf6, 0xad, 0xc9, 0xe0, 0xe7, 0x1b, 0x95, 0xa2, 0x82, 0x42, 0x51, 0x54, 0x28, 0xbf, 0x63, 0x51,
|
||||
0x61, 0x8b, 0x1b, 0xad, 0xdc, 0xd4, 0xd3, 0xff, 0xf1, 0xe0, 0x35, 0x00, 0x00, 0xff, 0xff, 0xa7,
|
||||
0xdd, 0xa1, 0x79, 0x9c, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// KeyManagementServiceClient is the client API for KeyManagementService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type KeyManagementServiceClient interface {
|
||||
// this API is meant to be polled
|
||||
Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error)
|
||||
// Execute decryption operation in KMS provider.
|
||||
Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error)
|
||||
// Execute encryption operation in KMS provider.
|
||||
Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error)
|
||||
}
|
||||
|
||||
type keyManagementServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClient {
|
||||
return &keyManagementServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *keyManagementServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
|
||||
out := new(StatusResponse)
|
||||
err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Status", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) {
|
||||
out := new(DecryptResponse)
|
||||
err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Decrypt", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) {
|
||||
out := new(EncryptResponse)
|
||||
err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Encrypt", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// KeyManagementServiceServer is the server API for KeyManagementService service.
|
||||
type KeyManagementServiceServer interface {
|
||||
// this API is meant to be polled
|
||||
Status(context.Context, *StatusRequest) (*StatusResponse, error)
|
||||
// Execute decryption operation in KMS provider.
|
||||
Decrypt(context.Context, *DecryptRequest) (*DecryptResponse, error)
|
||||
// Execute encryption operation in KMS provider.
|
||||
Encrypt(context.Context, *EncryptRequest) (*EncryptResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedKeyManagementServiceServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedKeyManagementServiceServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedKeyManagementServiceServer) Status(ctx context.Context, req *StatusRequest) (*StatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Status not implemented")
|
||||
}
|
||||
func (*UnimplementedKeyManagementServiceServer) Decrypt(ctx context.Context, req *DecryptRequest) (*DecryptResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Decrypt not implemented")
|
||||
}
|
||||
func (*UnimplementedKeyManagementServiceServer) Encrypt(ctx context.Context, req *EncryptRequest) (*EncryptResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Encrypt not implemented")
|
||||
}
|
||||
|
||||
func RegisterKeyManagementServiceServer(s *grpc.Server, srv KeyManagementServiceServer) {
|
||||
s.RegisterService(&_KeyManagementService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _KeyManagementService_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(StatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KeyManagementServiceServer).Status(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/v2alpha1.KeyManagementService/Status",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KeyManagementServiceServer).Status(ctx, req.(*StatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DecryptRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KeyManagementServiceServer).Decrypt(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/v2alpha1.KeyManagementService/Decrypt",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(EncryptRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KeyManagementServiceServer).Encrypt(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/v2alpha1.KeyManagementService/Encrypt",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _KeyManagementService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "v2alpha1.KeyManagementService",
|
||||
HandlerType: (*KeyManagementServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Status",
|
||||
Handler: _KeyManagementService_Status_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Decrypt",
|
||||
Handler: _KeyManagementService_Decrypt_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Encrypt",
|
||||
Handler: _KeyManagementService_Encrypt_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api.proto",
|
||||
}
|
||||
78
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1/api.proto
generated
vendored
78
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1/api.proto
generated
vendored
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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.
|
||||
*/
|
||||
|
||||
// To regenerate api.pb.go run hack/update-generated-kms.sh
|
||||
syntax = "proto3";
|
||||
|
||||
package v2alpha1;
|
||||
|
||||
// This service defines the public APIs for remote KMS provider.
|
||||
service KeyManagementService {
|
||||
// this API is meant to be polled
|
||||
rpc Status(StatusRequest) returns (StatusResponse) {}
|
||||
|
||||
// Execute decryption operation in KMS provider.
|
||||
rpc Decrypt(DecryptRequest) returns (DecryptResponse) {}
|
||||
// Execute encryption operation in KMS provider.
|
||||
rpc Encrypt(EncryptRequest) returns (EncryptResponse) {}
|
||||
}
|
||||
|
||||
message StatusRequest {}
|
||||
|
||||
message StatusResponse {
|
||||
// Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion
|
||||
string version = 1;
|
||||
// Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message.
|
||||
string healthz = 2;
|
||||
// the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage.
|
||||
string key_id = 3;
|
||||
}
|
||||
|
||||
message DecryptRequest {
|
||||
// The data to be decrypted.
|
||||
bytes ciphertext = 1;
|
||||
// UID is a unique identifier for the request.
|
||||
string uid = 2;
|
||||
// The keyID that was provided to the apiserver during encryption.
|
||||
// This represents the KMS KEK that was used to encrypt the data.
|
||||
string key_id = 3;
|
||||
// Additional metadata that was sent by the KMS plugin during encryption.
|
||||
map<string, bytes> annotations = 4;
|
||||
}
|
||||
|
||||
message DecryptResponse {
|
||||
// The decrypted data.
|
||||
bytes plaintext = 1;
|
||||
}
|
||||
|
||||
message EncryptRequest {
|
||||
// The data to be encrypted.
|
||||
bytes plaintext = 1;
|
||||
// UID is a unique identifier for the request.
|
||||
string uid = 2;
|
||||
}
|
||||
|
||||
message EncryptResponse {
|
||||
// The encrypted data.
|
||||
bytes ciphertext = 1;
|
||||
// The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use.
|
||||
// This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage.
|
||||
string key_id = 2;
|
||||
// Additional metadata to be stored with the encrypted data.
|
||||
// This metadata can contain the encrypted local KEK that was used to encrypt the DEK.
|
||||
// This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data.
|
||||
map<string, bytes> annotations = 3;
|
||||
}
|
||||
18
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1/v2alpha1.go
generated
vendored
18
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1/v2alpha1.go
generated
vendored
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 v2alpha1 contains definition of kms-plugin's gRPC service.
|
||||
package v2alpha1
|
||||
12
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go
generated
vendored
12
vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go
generated
vendored
@@ -24,6 +24,12 @@ import (
|
||||
"k8s.io/apiserver/pkg/storage/value"
|
||||
)
|
||||
|
||||
var (
|
||||
transformer = identityTransformer{}
|
||||
encryptedPrefix = []byte("k8s:enc:")
|
||||
errEncryptedData = fmt.Errorf("identity transformer tried to read encrypted data")
|
||||
)
|
||||
|
||||
// identityTransformer performs no transformation on provided data, but validates
|
||||
// that the data is not encrypted data during TransformFromStorage
|
||||
type identityTransformer struct{}
|
||||
@@ -31,7 +37,7 @@ type identityTransformer struct{}
|
||||
// NewEncryptCheckTransformer returns an identityTransformer which returns an error
|
||||
// on attempts to read encrypted data
|
||||
func NewEncryptCheckTransformer() value.Transformer {
|
||||
return identityTransformer{}
|
||||
return transformer
|
||||
}
|
||||
|
||||
// TransformFromStorage returns the input bytes if the data is not encrypted
|
||||
@@ -39,8 +45,8 @@ func (identityTransformer) TransformFromStorage(ctx context.Context, data []byte
|
||||
// identityTransformer has to return an error if the data is encoded using another transformer.
|
||||
// JSON data starts with '{'. Protobuf data has a prefix 'k8s[\x00-\xFF]'.
|
||||
// Prefix 'k8s:enc:' is reserved for encrypted data on disk.
|
||||
if bytes.HasPrefix(data, []byte("k8s:enc:")) {
|
||||
return []byte{}, false, fmt.Errorf("identity transformer tried to read encrypted data")
|
||||
if bytes.HasPrefix(data, encryptedPrefix) {
|
||||
return nil, false, errEncryptedData
|
||||
}
|
||||
return data, false, nil
|
||||
}
|
||||
|
||||
50
vendor/k8s.io/apiserver/pkg/storage/value/transformer.go
generated
vendored
50
vendor/k8s.io/apiserver/pkg/storage/value/transformer.go
generated
vendored
@@ -21,7 +21,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
@@ -51,54 +50,11 @@ type Transformer interface {
|
||||
TransformToStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, err error)
|
||||
}
|
||||
|
||||
type identityTransformer struct{}
|
||||
|
||||
// IdentityTransformer performs no transformation of the provided data.
|
||||
var IdentityTransformer Transformer = identityTransformer{}
|
||||
|
||||
func (identityTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, bool, error) {
|
||||
return data, false, nil
|
||||
}
|
||||
func (identityTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// DefaultContext is a simple implementation of Context for a slice of bytes.
|
||||
type DefaultContext []byte
|
||||
|
||||
// AuthenticatedData returns itself.
|
||||
func (c DefaultContext) AuthenticatedData() []byte { return []byte(c) }
|
||||
|
||||
// MutableTransformer allows a transformer to be changed safely at runtime.
|
||||
type MutableTransformer struct {
|
||||
lock sync.RWMutex
|
||||
transformer Transformer
|
||||
}
|
||||
|
||||
// NewMutableTransformer creates a transformer that can be updated at any time by calling Set()
|
||||
func NewMutableTransformer(transformer Transformer) *MutableTransformer {
|
||||
return &MutableTransformer{transformer: transformer}
|
||||
}
|
||||
|
||||
// Set updates the nested transformer.
|
||||
func (t *MutableTransformer) Set(transformer Transformer) {
|
||||
t.lock.Lock()
|
||||
t.transformer = transformer
|
||||
t.lock.Unlock()
|
||||
}
|
||||
|
||||
func (t *MutableTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, stale bool, err error) {
|
||||
t.lock.RLock()
|
||||
transformer := t.transformer
|
||||
t.lock.RUnlock()
|
||||
return transformer.TransformFromStorage(ctx, data, dataCtx)
|
||||
}
|
||||
func (t *MutableTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, err error) {
|
||||
t.lock.RLock()
|
||||
transformer := t.transformer
|
||||
t.lock.RUnlock()
|
||||
return transformer.TransformToStorage(ctx, data, dataCtx)
|
||||
}
|
||||
func (c DefaultContext) AuthenticatedData() []byte { return c }
|
||||
|
||||
// PrefixTransformer holds a transformer interface and the prefix that the transformation is located under.
|
||||
type PrefixTransformer struct {
|
||||
@@ -198,13 +154,13 @@ func (t *prefixTransformers) TransformFromStorage(ctx context.Context, data []by
|
||||
func (t *prefixTransformers) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, error) {
|
||||
start := time.Now()
|
||||
transformer := t.transformers[0]
|
||||
prefixedData := make([]byte, len(transformer.Prefix), len(data)+len(transformer.Prefix))
|
||||
copy(prefixedData, transformer.Prefix)
|
||||
result, err := transformer.Transformer.TransformToStorage(ctx, data, dataCtx)
|
||||
RecordTransformation("to_storage", string(transformer.Prefix), start, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prefixedData := make([]byte, len(transformer.Prefix), len(result)+len(transformer.Prefix))
|
||||
copy(prefixedData, transformer.Prefix)
|
||||
prefixedData = append(prefixedData, result...)
|
||||
return prefixedData, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user