git mv Ingress ingress
This commit is contained in:
parent
34b949c134
commit
3da4e74e5a
2185 changed files with 754743 additions and 0 deletions
550
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go
generated
vendored
Normal file
550
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go
generated
vendored
Normal file
|
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// NewDeltaFIFO returns a Store which can be used process changes to items.
|
||||
//
|
||||
// keyFunc is used to figure out what key an object should have. (It's
|
||||
// exposed in the returned DeltaFIFO's KeyOf() method, with bonus features.)
|
||||
//
|
||||
// 'compressor' may compress as many or as few items as it wants
|
||||
// (including returning an empty slice), but it should do what it
|
||||
// does quickly since it is called while the queue is locked.
|
||||
// 'compressor' may be nil if you don't want any delta compression.
|
||||
//
|
||||
// 'keyLister' is expected to return a list of keys that the consumer of
|
||||
// this queue "knows about". It is used to decide which items are missing
|
||||
// when Replace() is called; 'Deleted' deltas are produced for these items.
|
||||
// It may be nil if you don't need to detect all deletions.
|
||||
// TODO: consider merging keyLister with this object, tracking a list of
|
||||
// "known" keys when Pop() is called. Have to think about how that
|
||||
// affects error retrying.
|
||||
// TODO(lavalamp): I believe there is a possible race only when using an
|
||||
// external known object source that the above TODO would
|
||||
// fix.
|
||||
//
|
||||
// Also see the comment on DeltaFIFO.
|
||||
func NewDeltaFIFO(keyFunc KeyFunc, compressor DeltaCompressor, knownObjects KeyListerGetter) *DeltaFIFO {
|
||||
f := &DeltaFIFO{
|
||||
items: map[string]Deltas{},
|
||||
queue: []string{},
|
||||
keyFunc: keyFunc,
|
||||
deltaCompressor: compressor,
|
||||
knownObjects: knownObjects,
|
||||
}
|
||||
f.cond.L = &f.lock
|
||||
return f
|
||||
}
|
||||
|
||||
// DeltaFIFO is like FIFO, but allows you to process deletes.
|
||||
//
|
||||
// DeltaFIFO is a producer-consumer queue, where a Reflector is
|
||||
// intended to be the producer, and the consumer is whatever calls
|
||||
// the Pop() method.
|
||||
//
|
||||
// DeltaFIFO solves this use case:
|
||||
// * You want to process every object change (delta) at most once.
|
||||
// * When you process an object, you want to see everything
|
||||
// that's happened to it since you last processed it.
|
||||
// * You want to process the deletion of objects.
|
||||
// * You might want to periodically reprocess objects.
|
||||
//
|
||||
// DeltaFIFO's Pop(), Get(), and GetByKey() methods return
|
||||
// interface{} to satisfy the Store/Queue interfaces, but it
|
||||
// will always return an object of type Deltas.
|
||||
//
|
||||
// A note on threading: If you call Pop() in parallel from multiple
|
||||
// threads, you could end up with multiple threads processing slightly
|
||||
// different versions of the same object.
|
||||
//
|
||||
// A note on the KeyLister used by the DeltaFIFO: It's main purpose is
|
||||
// to list keys that are "known", for the puspose of figuring out which
|
||||
// items have been deleted when Replace() or Delete() are called. The deleted
|
||||
// objet will be included in the DeleteFinalStateUnknown markers. These objects
|
||||
// could be stale.
|
||||
//
|
||||
// You may provide a function to compress deltas (e.g., represent a
|
||||
// series of Updates as a single Update).
|
||||
type DeltaFIFO struct {
|
||||
// lock/cond protects access to 'items' and 'queue'.
|
||||
lock sync.RWMutex
|
||||
cond sync.Cond
|
||||
|
||||
// We depend on the property that items in the set are in
|
||||
// the queue and vice versa, and that all Deltas in this
|
||||
// map have at least one Delta.
|
||||
items map[string]Deltas
|
||||
queue []string
|
||||
|
||||
// populated is true if the first batch of items inserted by Replace() has been populated
|
||||
// or Delete/Add/Update was called first.
|
||||
populated bool
|
||||
// initialPopulationCount is the number of items inserted by the first call of Replace()
|
||||
initialPopulationCount int
|
||||
|
||||
// keyFunc is used to make the key used for queued item
|
||||
// insertion and retrieval, and should be deterministic.
|
||||
keyFunc KeyFunc
|
||||
|
||||
// deltaCompressor tells us how to combine two or more
|
||||
// deltas. It may be nil.
|
||||
deltaCompressor DeltaCompressor
|
||||
|
||||
// knownObjects list keys that are "known", for the
|
||||
// purpose of figuring out which items have been deleted
|
||||
// when Replace() or Delete() is called.
|
||||
knownObjects KeyListerGetter
|
||||
}
|
||||
|
||||
var (
|
||||
_ = Queue(&DeltaFIFO{}) // DeltaFIFO is a Queue
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrZeroLengthDeltasObject is returned in a KeyError if a Deltas
|
||||
// object with zero length is encountered (should be impossible,
|
||||
// even if such an object is accidentally produced by a DeltaCompressor--
|
||||
// but included for completeness).
|
||||
ErrZeroLengthDeltasObject = errors.New("0 length Deltas object; can't get key")
|
||||
)
|
||||
|
||||
// KeyOf exposes f's keyFunc, but also detects the key of a Deltas object or
|
||||
// DeletedFinalStateUnknown objects.
|
||||
func (f *DeltaFIFO) KeyOf(obj interface{}) (string, error) {
|
||||
if d, ok := obj.(Deltas); ok {
|
||||
if len(d) == 0 {
|
||||
return "", KeyError{obj, ErrZeroLengthDeltasObject}
|
||||
}
|
||||
obj = d.Newest().Object
|
||||
}
|
||||
if d, ok := obj.(DeletedFinalStateUnknown); ok {
|
||||
return d.Key, nil
|
||||
}
|
||||
return f.keyFunc(obj)
|
||||
}
|
||||
|
||||
// Return true if an Add/Update/Delete/AddIfNotPresent are called first,
|
||||
// or an Update called first but the first batch of items inserted by Replace() has been popped
|
||||
func (f *DeltaFIFO) HasSynced() bool {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
return f.populated && f.initialPopulationCount == 0
|
||||
}
|
||||
|
||||
// Add inserts an item, and puts it in the queue. The item is only enqueued
|
||||
// if it doesn't already exist in the set.
|
||||
func (f *DeltaFIFO) Add(obj interface{}) error {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.populated = true
|
||||
return f.queueActionLocked(Added, obj)
|
||||
}
|
||||
|
||||
// Update is just like Add, but makes an Updated Delta.
|
||||
func (f *DeltaFIFO) Update(obj interface{}) error {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.populated = true
|
||||
return f.queueActionLocked(Updated, obj)
|
||||
}
|
||||
|
||||
// Delete is just like Add, but makes an Deleted Delta. If the item does not
|
||||
// already exist, it will be ignored. (It may have already been deleted by a
|
||||
// Replace (re-list), for example.
|
||||
func (f *DeltaFIFO) Delete(obj interface{}) error {
|
||||
id, err := f.KeyOf(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.populated = true
|
||||
if f.knownObjects == nil {
|
||||
if _, exists := f.items[id]; !exists {
|
||||
// Presumably, this was deleted when a relist happened.
|
||||
// Don't provide a second report of the same deletion.
|
||||
return nil
|
||||
}
|
||||
} else if _, exists, err := f.knownObjects.GetByKey(id); err == nil && !exists {
|
||||
// Presumably, this was deleted when a relist happened.
|
||||
// Don't provide a second report of the same deletion.
|
||||
// TODO(lavalamp): This may be racy-- we aren't properly locked
|
||||
// with knownObjects.
|
||||
return nil
|
||||
}
|
||||
|
||||
return f.queueActionLocked(Deleted, obj)
|
||||
}
|
||||
|
||||
// AddIfNotPresent inserts an item, and puts it in the queue. If the item is already
|
||||
// present in the set, it is neither enqueued nor added to the set.
|
||||
//
|
||||
// This is useful in a single producer/consumer scenario so that the consumer can
|
||||
// safely retry items without contending with the producer and potentially enqueueing
|
||||
// stale items.
|
||||
//
|
||||
// Important: obj must be a Deltas (the output of the Pop() function). Yes, this is
|
||||
// different from the Add/Update/Delete functions.
|
||||
func (f *DeltaFIFO) AddIfNotPresent(obj interface{}) error {
|
||||
deltas, ok := obj.(Deltas)
|
||||
if !ok {
|
||||
return fmt.Errorf("object must be of type deltas, but got: %#v", obj)
|
||||
}
|
||||
id, err := f.KeyOf(deltas.Newest().Object)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.populated = true
|
||||
if _, exists := f.items[id]; exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.queue = append(f.queue, id)
|
||||
f.items[id] = deltas
|
||||
f.cond.Broadcast()
|
||||
return nil
|
||||
}
|
||||
|
||||
// re-listing and watching can deliver the same update multiple times in any
|
||||
// order. This will combine the most recent two deltas if they are the same.
|
||||
func dedupDeltas(deltas Deltas) Deltas {
|
||||
n := len(deltas)
|
||||
if n < 2 {
|
||||
return deltas
|
||||
}
|
||||
a := &deltas[n-1]
|
||||
b := &deltas[n-2]
|
||||
if out := isDup(a, b); out != nil {
|
||||
d := append(Deltas{}, deltas[:n-2]...)
|
||||
return append(d, *out)
|
||||
}
|
||||
return deltas
|
||||
}
|
||||
|
||||
// If a & b represent the same event, returns the delta that ought to be kept.
|
||||
// Otherwise, returns nil.
|
||||
// TODO: is there anything other than deletions that need deduping?
|
||||
func isDup(a, b *Delta) *Delta {
|
||||
if out := isDeletionDup(a, b); out != nil {
|
||||
return out
|
||||
}
|
||||
// TODO: Detect other duplicate situations? Are there any?
|
||||
return nil
|
||||
}
|
||||
|
||||
// keep the one with the most information if both are deletions.
|
||||
func isDeletionDup(a, b *Delta) *Delta {
|
||||
if b.Type != Deleted || a.Type != Deleted {
|
||||
return nil
|
||||
}
|
||||
// Do more sophisticated checks, or is this sufficient?
|
||||
if _, ok := b.Object.(DeletedFinalStateUnknown); ok {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// queueActionLocked appends to the delta list for the object, calling
|
||||
// f.deltaCompressor if needed. Caller must lock first.
|
||||
func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) error {
|
||||
id, err := f.KeyOf(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
newDeltas := append(f.items[id], Delta{actionType, obj})
|
||||
newDeltas = dedupDeltas(newDeltas)
|
||||
if f.deltaCompressor != nil {
|
||||
newDeltas = f.deltaCompressor.Compress(newDeltas)
|
||||
}
|
||||
|
||||
_, exists := f.items[id]
|
||||
if len(newDeltas) > 0 {
|
||||
if !exists {
|
||||
f.queue = append(f.queue, id)
|
||||
}
|
||||
f.items[id] = newDeltas
|
||||
f.cond.Broadcast()
|
||||
} else if exists {
|
||||
// The compression step removed all deltas, so
|
||||
// we need to remove this from our map (extra items
|
||||
// in the queue are ignored if they are not in the
|
||||
// map).
|
||||
delete(f.items, id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns a list of all the items; it returns the object
|
||||
// from the most recent Delta.
|
||||
// You should treat the items returned inside the deltas as immutable.
|
||||
func (f *DeltaFIFO) List() []interface{} {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
list := make([]interface{}, 0, len(f.items))
|
||||
for _, item := range f.items {
|
||||
// Copy item's slice so operations on this slice (delta
|
||||
// compression) won't interfere with the object we return.
|
||||
item = copyDeltas(item)
|
||||
list = append(list, item.Newest().Object)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// ListKeys returns a list of all the keys of the objects currently
|
||||
// in the FIFO.
|
||||
func (f *DeltaFIFO) ListKeys() []string {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
list := make([]string, 0, len(f.items))
|
||||
for key := range f.items {
|
||||
list = append(list, key)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// Get returns the complete list of deltas for the requested item,
|
||||
// or sets exists=false.
|
||||
// You should treat the items returned inside the deltas as immutable.
|
||||
func (f *DeltaFIFO) Get(obj interface{}) (item interface{}, exists bool, err error) {
|
||||
key, err := f.KeyOf(obj)
|
||||
if err != nil {
|
||||
return nil, false, KeyError{obj, err}
|
||||
}
|
||||
return f.GetByKey(key)
|
||||
}
|
||||
|
||||
// GetByKey returns the complete list of deltas for the requested item,
|
||||
// setting exists=false if that list is empty.
|
||||
// You should treat the items returned inside the deltas as immutable.
|
||||
func (f *DeltaFIFO) GetByKey(key string) (item interface{}, exists bool, err error) {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
d, exists := f.items[key]
|
||||
if exists {
|
||||
// Copy item's slice so operations on this slice (delta
|
||||
// compression) won't interfere with the object we return.
|
||||
d = copyDeltas(d)
|
||||
}
|
||||
return d, exists, nil
|
||||
}
|
||||
|
||||
// Pop blocks until an item is added to the queue, and then returns it. If
|
||||
// multiple items are ready, they are returned in the order in which they were
|
||||
// added/updated. The item is removed from the queue (and the store) before it
|
||||
// is returned, so if you don't successfully process it, you need to add it back
|
||||
// with AddIfNotPresent().
|
||||
//
|
||||
// Pop returns a 'Deltas', which has a complete list of all the things
|
||||
// that happened to the object (deltas) while it was sitting in the queue.
|
||||
func (f *DeltaFIFO) Pop() interface{} {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
for {
|
||||
for len(f.queue) == 0 {
|
||||
f.cond.Wait()
|
||||
}
|
||||
id := f.queue[0]
|
||||
f.queue = f.queue[1:]
|
||||
item, ok := f.items[id]
|
||||
if f.initialPopulationCount > 0 {
|
||||
f.initialPopulationCount--
|
||||
}
|
||||
if !ok {
|
||||
// Item may have been deleted subsequently.
|
||||
continue
|
||||
}
|
||||
delete(f.items, id)
|
||||
// Don't need to copyDeltas here, because we're transferring
|
||||
// ownership to the caller.
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
// Replace will delete the contents of 'f', using instead the given map.
|
||||
// 'f' takes ownership of the map, you should not reference the map again
|
||||
// after calling this function. f's queue is reset, too; upon return, it
|
||||
// will contain the items in the map, in no particular order.
|
||||
func (f *DeltaFIFO) Replace(list []interface{}, resourceVersion string) error {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
keys := make(sets.String, len(list))
|
||||
|
||||
if !f.populated {
|
||||
f.populated = true
|
||||
f.initialPopulationCount = len(list)
|
||||
}
|
||||
|
||||
for _, item := range list {
|
||||
key, err := f.KeyOf(item)
|
||||
if err != nil {
|
||||
return KeyError{item, err}
|
||||
}
|
||||
keys.Insert(key)
|
||||
if err := f.queueActionLocked(Sync, item); err != nil {
|
||||
return fmt.Errorf("couldn't enqueue object: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if f.knownObjects == nil {
|
||||
// Do deletion detection against our own list.
|
||||
for k, oldItem := range f.items {
|
||||
if keys.Has(k) {
|
||||
continue
|
||||
}
|
||||
var deletedObj interface{}
|
||||
if n := oldItem.Newest(); n != nil {
|
||||
deletedObj = n.Object
|
||||
}
|
||||
if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Detect deletions not already in the queue.
|
||||
// TODO(lavalamp): This may be racy-- we aren't properly locked
|
||||
// with knownObjects. Unproven.
|
||||
knownKeys := f.knownObjects.ListKeys()
|
||||
for _, k := range knownKeys {
|
||||
if keys.Has(k) {
|
||||
continue
|
||||
}
|
||||
|
||||
deletedObj, exists, err := f.knownObjects.GetByKey(k)
|
||||
if err != nil {
|
||||
deletedObj = nil
|
||||
glog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k)
|
||||
} else if !exists {
|
||||
deletedObj = nil
|
||||
glog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k)
|
||||
}
|
||||
if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A KeyListerGetter is anything that knows how to list its keys and look up by key.
|
||||
type KeyListerGetter interface {
|
||||
KeyLister
|
||||
KeyGetter
|
||||
}
|
||||
|
||||
// A KeyLister is anything that knows how to list its keys.
|
||||
type KeyLister interface {
|
||||
ListKeys() []string
|
||||
}
|
||||
|
||||
// A KeyGetter is anything that knows how to get the value stored under a given key.
|
||||
type KeyGetter interface {
|
||||
GetByKey(key string) (interface{}, bool, error)
|
||||
}
|
||||
|
||||
// DeltaCompressor is an algorithm that removes redundant changes.
|
||||
type DeltaCompressor interface {
|
||||
Compress(Deltas) Deltas
|
||||
}
|
||||
|
||||
// DeltaCompressorFunc should remove redundant changes; but changes that
|
||||
// are redundant depend on one's desired semantics, so this is an
|
||||
// injectable function.
|
||||
//
|
||||
// DeltaCompressorFunc adapts a raw function to be a DeltaCompressor.
|
||||
type DeltaCompressorFunc func(Deltas) Deltas
|
||||
|
||||
// Compress just calls dc.
|
||||
func (dc DeltaCompressorFunc) Compress(d Deltas) Deltas {
|
||||
return dc(d)
|
||||
}
|
||||
|
||||
// DeltaType is the type of a change (addition, deletion, etc)
|
||||
type DeltaType string
|
||||
|
||||
const (
|
||||
Added DeltaType = "Added"
|
||||
Updated DeltaType = "Updated"
|
||||
Deleted DeltaType = "Deleted"
|
||||
// The other types are obvious. You'll get Sync deltas when:
|
||||
// * A watch expires/errors out and a new list/watch cycle is started.
|
||||
// * You've turned on periodic syncs.
|
||||
// (Anything that trigger's DeltaFIFO's Replace() method.)
|
||||
Sync DeltaType = "Sync"
|
||||
)
|
||||
|
||||
// Delta is the type stored by a DeltaFIFO. It tells you what change
|
||||
// happened, and the object's state after* that change.
|
||||
//
|
||||
// [*] Unless the change is a deletion, and then you'll get the final
|
||||
// state of the object before it was deleted.
|
||||
type Delta struct {
|
||||
Type DeltaType
|
||||
Object interface{}
|
||||
}
|
||||
|
||||
// Deltas is a list of one or more 'Delta's to an individual object.
|
||||
// The oldest delta is at index 0, the newest delta is the last one.
|
||||
type Deltas []Delta
|
||||
|
||||
// Oldest is a convenience function that returns the oldest delta, or
|
||||
// nil if there are no deltas.
|
||||
func (d Deltas) Oldest() *Delta {
|
||||
if len(d) > 0 {
|
||||
return &d[0]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Newest is a convenience function that returns the newest delta, or
|
||||
// nil if there are no deltas.
|
||||
func (d Deltas) Newest() *Delta {
|
||||
if n := len(d); n > 0 {
|
||||
return &d[n-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// copyDeltas returns a shallow copy of d; that is, it copies the slice but not
|
||||
// the objects in the slice. This allows Get/List to return an object that we
|
||||
// know won't be clobbered by a subsequent call to a delta compressor.
|
||||
func copyDeltas(d Deltas) Deltas {
|
||||
d2 := make(Deltas, len(d))
|
||||
copy(d2, d)
|
||||
return d2
|
||||
}
|
||||
|
||||
// DeletedFinalStateUnknown is placed into a DeltaFIFO in the case where
|
||||
// an object was deleted but the watch deletion event was missed. In this
|
||||
// case we don't know the final "resting" state of the object, so there's
|
||||
// a chance the included `Obj` is stale.
|
||||
type DeletedFinalStateUnknown struct {
|
||||
Key string
|
||||
Obj interface{}
|
||||
}
|
||||
385
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/delta_fifo_test.go
generated
vendored
Normal file
385
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/delta_fifo_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// helper function to reduce stuttering
|
||||
func testPop(f *DeltaFIFO) testFifoObject {
|
||||
return f.Pop().(Deltas).Newest().Object.(testFifoObject)
|
||||
}
|
||||
|
||||
// keyLookupFunc adapts a raw function to be a KeyLookup.
|
||||
type keyLookupFunc func() []string
|
||||
|
||||
// ListKeys just calls kl.
|
||||
func (kl keyLookupFunc) ListKeys() []string {
|
||||
return kl()
|
||||
}
|
||||
|
||||
// GetByKey returns the key if it exists in the list returned by kl.
|
||||
func (kl keyLookupFunc) GetByKey(key string) (interface{}, bool, error) {
|
||||
for _, v := range kl() {
|
||||
if v == key {
|
||||
return key, true, nil
|
||||
}
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_basic(t *testing.T) {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil)
|
||||
const amount = 500
|
||||
go func() {
|
||||
for i := 0; i < amount; i++ {
|
||||
f.Add(mkFifoObj(string([]rune{'a', rune(i)}), i+1))
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for u := uint64(0); u < amount; u++ {
|
||||
f.Add(mkFifoObj(string([]rune{'b', rune(u)}), u+1))
|
||||
}
|
||||
}()
|
||||
|
||||
lastInt := int(0)
|
||||
lastUint := uint64(0)
|
||||
for i := 0; i < amount*2; i++ {
|
||||
switch obj := testPop(f).val.(type) {
|
||||
case int:
|
||||
if obj <= lastInt {
|
||||
t.Errorf("got %v (int) out of order, last was %v", obj, lastInt)
|
||||
}
|
||||
lastInt = obj
|
||||
case uint64:
|
||||
if obj <= lastUint {
|
||||
t.Errorf("got %v (uint) out of order, last was %v", obj, lastUint)
|
||||
} else {
|
||||
lastUint = obj
|
||||
}
|
||||
default:
|
||||
t.Fatalf("unexpected type %#v", obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_compressorWorks(t *testing.T) {
|
||||
oldestTypes := []DeltaType{}
|
||||
f := NewDeltaFIFO(
|
||||
testFifoObjectKeyFunc,
|
||||
// This function just keeps the most recent delta
|
||||
// and puts deleted ones in the list.
|
||||
DeltaCompressorFunc(func(d Deltas) Deltas {
|
||||
if n := len(d); n > 1 {
|
||||
oldestTypes = append(oldestTypes, d[0].Type)
|
||||
d = d[1:]
|
||||
}
|
||||
return d
|
||||
}),
|
||||
nil,
|
||||
)
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Update(mkFifoObj("foo", 12))
|
||||
f.Replace([]interface{}{mkFifoObj("foo", 20)}, "0")
|
||||
f.Delete(mkFifoObj("foo", 22))
|
||||
f.Add(mkFifoObj("foo", 25)) // flush the last one out
|
||||
expect := []DeltaType{Added, Updated, Sync, Deleted}
|
||||
if e, a := expect, oldestTypes; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %#v, got %#v", e, a)
|
||||
}
|
||||
if e, a := (Deltas{{Added, mkFifoObj("foo", 25)}}), f.Pop().(Deltas); !reflect.DeepEqual(e, a) {
|
||||
t.Fatalf("Expected %#v, got %#v", e, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_addUpdate(t *testing.T) {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil)
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Update(mkFifoObj("foo", 12))
|
||||
f.Delete(mkFifoObj("foo", 15))
|
||||
|
||||
if e, a := []interface{}{mkFifoObj("foo", 15)}, f.List(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %+v, got %+v", e, a)
|
||||
}
|
||||
if e, a := []string{"foo"}, f.ListKeys(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %+v, got %+v", e, a)
|
||||
}
|
||||
|
||||
got := make(chan testFifoObject, 2)
|
||||
go func() {
|
||||
for {
|
||||
obj := f.Pop().(Deltas).Newest().Object.(testFifoObject)
|
||||
t.Logf("got a thing %#v", obj)
|
||||
t.Logf("D len: %v", len(f.queue))
|
||||
got <- obj
|
||||
}
|
||||
}()
|
||||
|
||||
first := <-got
|
||||
if e, a := 15, first.val; e != a {
|
||||
t.Errorf("Didn't get updated value (%v), got %v", e, a)
|
||||
}
|
||||
select {
|
||||
case unexpected := <-got:
|
||||
t.Errorf("Got second value %v", unexpected.val)
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
_, exists, _ := f.Get(mkFifoObj("foo", ""))
|
||||
if exists {
|
||||
t.Errorf("item did not get removed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_enqueueingNoLister(t *testing.T) {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil)
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Update(mkFifoObj("bar", 15))
|
||||
f.Add(mkFifoObj("qux", 17))
|
||||
f.Delete(mkFifoObj("qux", 18))
|
||||
|
||||
// This delete does not enqueue anything because baz doesn't exist.
|
||||
f.Delete(mkFifoObj("baz", 20))
|
||||
|
||||
expectList := []int{10, 15, 18}
|
||||
for _, expect := range expectList {
|
||||
if e, a := expect, testPop(f).val; e != a {
|
||||
t.Errorf("Didn't get updated value (%v), got %v", e, a)
|
||||
}
|
||||
}
|
||||
if e, a := 0, len(f.items); e != a {
|
||||
t.Errorf("queue unexpectedly not empty: %v != %v\n%#v", e, a, f.items)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_enqueueingWithLister(t *testing.T) {
|
||||
f := NewDeltaFIFO(
|
||||
testFifoObjectKeyFunc,
|
||||
nil,
|
||||
keyLookupFunc(func() []string {
|
||||
return []string{"foo", "bar", "baz"}
|
||||
}),
|
||||
)
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Update(mkFifoObj("bar", 15))
|
||||
|
||||
// This delete does enqueue the deletion, because "baz" is in the key lister.
|
||||
f.Delete(mkFifoObj("baz", 20))
|
||||
|
||||
expectList := []int{10, 15, 20}
|
||||
for _, expect := range expectList {
|
||||
if e, a := expect, testPop(f).val; e != a {
|
||||
t.Errorf("Didn't get updated value (%v), got %v", e, a)
|
||||
}
|
||||
}
|
||||
if e, a := 0, len(f.items); e != a {
|
||||
t.Errorf("queue unexpectedly not empty: %v != %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_addReplace(t *testing.T) {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil)
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Replace([]interface{}{mkFifoObj("foo", 15)}, "0")
|
||||
got := make(chan testFifoObject, 2)
|
||||
go func() {
|
||||
for {
|
||||
got <- testPop(f)
|
||||
}
|
||||
}()
|
||||
|
||||
first := <-got
|
||||
if e, a := 15, first.val; e != a {
|
||||
t.Errorf("Didn't get updated value (%v), got %v", e, a)
|
||||
}
|
||||
select {
|
||||
case unexpected := <-got:
|
||||
t.Errorf("Got second value %v", unexpected.val)
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
_, exists, _ := f.Get(mkFifoObj("foo", ""))
|
||||
if exists {
|
||||
t.Errorf("item did not get removed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_ReplaceMakesDeletions(t *testing.T) {
|
||||
f := NewDeltaFIFO(
|
||||
testFifoObjectKeyFunc,
|
||||
nil,
|
||||
keyLookupFunc(func() []string {
|
||||
return []string{"foo", "bar", "baz"}
|
||||
}),
|
||||
)
|
||||
f.Delete(mkFifoObj("baz", 10))
|
||||
f.Replace([]interface{}{mkFifoObj("foo", 5)}, "0")
|
||||
|
||||
expectedList := []Deltas{
|
||||
{{Deleted, mkFifoObj("baz", 10)}},
|
||||
{{Sync, mkFifoObj("foo", 5)}},
|
||||
// Since "bar" didn't have a delete event and wasn't in the Replace list
|
||||
// it should get a tombstone key with the right Obj.
|
||||
{{Deleted, DeletedFinalStateUnknown{Key: "bar", Obj: "bar"}}},
|
||||
}
|
||||
|
||||
for _, expected := range expectedList {
|
||||
cur := f.Pop().(Deltas)
|
||||
if e, a := expected, cur; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %#v, got %#v", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_detectLineJumpers(t *testing.T) {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil)
|
||||
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Add(mkFifoObj("bar", 1))
|
||||
f.Add(mkFifoObj("foo", 11))
|
||||
f.Add(mkFifoObj("foo", 13))
|
||||
f.Add(mkFifoObj("zab", 30))
|
||||
|
||||
if e, a := 13, testPop(f).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
f.Add(mkFifoObj("foo", 14)) // ensure foo doesn't jump back in line
|
||||
|
||||
if e, a := 1, testPop(f).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
if e, a := 30, testPop(f).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
if e, a := 14, testPop(f).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_addIfNotPresent(t *testing.T) {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil)
|
||||
|
||||
f.Add(mkFifoObj("b", 3))
|
||||
b3 := f.Pop()
|
||||
f.Add(mkFifoObj("c", 4))
|
||||
c4 := f.Pop()
|
||||
if e, a := 0, len(f.items); e != a {
|
||||
t.Fatalf("Expected %v, got %v items in queue", e, a)
|
||||
}
|
||||
|
||||
f.Add(mkFifoObj("a", 1))
|
||||
f.Add(mkFifoObj("b", 2))
|
||||
f.AddIfNotPresent(b3)
|
||||
f.AddIfNotPresent(c4)
|
||||
|
||||
if e, a := 3, len(f.items); a != e {
|
||||
t.Fatalf("expected queue length %d, got %d", e, a)
|
||||
}
|
||||
|
||||
expectedValues := []int{1, 2, 4}
|
||||
for _, expected := range expectedValues {
|
||||
if actual := testPop(f).val; actual != expected {
|
||||
t.Fatalf("expected value %d, got %d", expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_KeyOf(t *testing.T) {
|
||||
f := DeltaFIFO{keyFunc: testFifoObjectKeyFunc}
|
||||
|
||||
table := []struct {
|
||||
obj interface{}
|
||||
key string
|
||||
}{
|
||||
{obj: testFifoObject{name: "A"}, key: "A"},
|
||||
{obj: DeletedFinalStateUnknown{Key: "B", Obj: nil}, key: "B"},
|
||||
{obj: Deltas{{Object: testFifoObject{name: "C"}}}, key: "C"},
|
||||
{obj: Deltas{{Object: DeletedFinalStateUnknown{Key: "D", Obj: nil}}}, key: "D"},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
got, err := f.KeyOf(item.obj)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error for %q: %v", item.obj, err)
|
||||
continue
|
||||
}
|
||||
if e, a := item.key, got; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_HasSynced(t *testing.T) {
|
||||
tests := []struct {
|
||||
actions []func(f *DeltaFIFO)
|
||||
expectedSynced bool
|
||||
}{
|
||||
{
|
||||
actions: []func(f *DeltaFIFO){},
|
||||
expectedSynced: false,
|
||||
},
|
||||
{
|
||||
actions: []func(f *DeltaFIFO){
|
||||
func(f *DeltaFIFO) { f.Add(mkFifoObj("a", 1)) },
|
||||
},
|
||||
expectedSynced: true,
|
||||
},
|
||||
{
|
||||
actions: []func(f *DeltaFIFO){
|
||||
func(f *DeltaFIFO) { f.Replace([]interface{}{}, "0") },
|
||||
},
|
||||
expectedSynced: true,
|
||||
},
|
||||
{
|
||||
actions: []func(f *DeltaFIFO){
|
||||
func(f *DeltaFIFO) { f.Replace([]interface{}{mkFifoObj("a", 1), mkFifoObj("b", 2)}, "0") },
|
||||
},
|
||||
expectedSynced: false,
|
||||
},
|
||||
{
|
||||
actions: []func(f *DeltaFIFO){
|
||||
func(f *DeltaFIFO) { f.Replace([]interface{}{mkFifoObj("a", 1), mkFifoObj("b", 2)}, "0") },
|
||||
func(f *DeltaFIFO) { f.Pop() },
|
||||
},
|
||||
expectedSynced: false,
|
||||
},
|
||||
{
|
||||
actions: []func(f *DeltaFIFO){
|
||||
func(f *DeltaFIFO) { f.Replace([]interface{}{mkFifoObj("a", 1), mkFifoObj("b", 2)}, "0") },
|
||||
func(f *DeltaFIFO) { f.Pop() },
|
||||
func(f *DeltaFIFO) { f.Pop() },
|
||||
},
|
||||
expectedSynced: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil, nil)
|
||||
|
||||
for _, action := range test.actions {
|
||||
action(f)
|
||||
}
|
||||
if e, a := test.expectedSynced, f.HasSynced(); a != e {
|
||||
t.Errorf("test case %v failed, expected: %v , got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/doc.go
generated
vendored
Normal file
24
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache is a client-side caching mechanism. It is useful for
|
||||
// reducing the number of server calls you'd otherwise need to make.
|
||||
// Reflector watches a server and updates a Store. Two stores are provided;
|
||||
// one that simply caches objects (for example, to allow a scheduler to
|
||||
// list currently available nodes), and one that additionally acts as
|
||||
// a FIFO queue (for example, to allow a scheduler to process incoming
|
||||
// pods).
|
||||
package cache
|
||||
193
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go
generated
vendored
Normal file
193
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/runtime"
|
||||
)
|
||||
|
||||
// ExpirationCache implements the store interface
|
||||
// 1. All entries are automatically time stamped on insert
|
||||
// a. The key is computed based off the original item/keyFunc
|
||||
// b. The value inserted under that key is the timestamped item
|
||||
// 2. Expiration happens lazily on read based on the expiration policy
|
||||
// 3. Time-stamps are stripped off unexpired entries before return
|
||||
type ExpirationCache struct {
|
||||
cacheStorage ThreadSafeStore
|
||||
keyFunc KeyFunc
|
||||
clock util.Clock
|
||||
expirationPolicy ExpirationPolicy
|
||||
}
|
||||
|
||||
// ExpirationPolicy dictates when an object expires. Currently only abstracted out
|
||||
// so unittests don't rely on the system clock.
|
||||
type ExpirationPolicy interface {
|
||||
IsExpired(obj *timestampedEntry) bool
|
||||
}
|
||||
|
||||
// TTLPolicy implements a ttl based ExpirationPolicy.
|
||||
type TTLPolicy struct {
|
||||
// >0: Expire entries with an age > ttl
|
||||
// <=0: Don't expire any entry
|
||||
Ttl time.Duration
|
||||
|
||||
// Clock used to calculate ttl expiration
|
||||
Clock util.Clock
|
||||
}
|
||||
|
||||
// IsExpired returns true if the given object is older than the ttl, or it can't
|
||||
// determine its age.
|
||||
func (p *TTLPolicy) IsExpired(obj *timestampedEntry) bool {
|
||||
return p.Ttl > 0 && p.Clock.Since(obj.timestamp) > p.Ttl
|
||||
}
|
||||
|
||||
// timestampedEntry is the only type allowed in a ExpirationCache.
|
||||
type timestampedEntry struct {
|
||||
obj interface{}
|
||||
timestamp time.Time
|
||||
}
|
||||
|
||||
// getTimestampedEntry returnes the timestampedEntry stored under the given key.
|
||||
func (c *ExpirationCache) getTimestampedEntry(key string) (*timestampedEntry, bool) {
|
||||
item, _ := c.cacheStorage.Get(key)
|
||||
// TODO: Check the cast instead
|
||||
if tsEntry, ok := item.(*timestampedEntry); ok {
|
||||
return tsEntry, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// getOrExpire retrieves the object from the timestampedEntry if and only if it hasn't
|
||||
// already expired. It kicks-off a go routine to delete expired objects from
|
||||
// the store and sets exists=false.
|
||||
func (c *ExpirationCache) getOrExpire(key string) (interface{}, bool) {
|
||||
timestampedItem, exists := c.getTimestampedEntry(key)
|
||||
if !exists {
|
||||
return nil, false
|
||||
}
|
||||
if c.expirationPolicy.IsExpired(timestampedItem) {
|
||||
glog.V(4).Infof("Entry %v: %+v has expired", key, timestampedItem.obj)
|
||||
// Since expiration happens lazily on read, don't hold up
|
||||
// the reader trying to acquire a write lock for the delete.
|
||||
// The next reader will retry the delete even if this one
|
||||
// fails; as long as we only return un-expired entries a
|
||||
// reader doesn't need to wait for the result of the delete.
|
||||
go func() {
|
||||
defer runtime.HandleCrash()
|
||||
c.cacheStorage.Delete(key)
|
||||
}()
|
||||
return nil, false
|
||||
}
|
||||
return timestampedItem.obj, true
|
||||
}
|
||||
|
||||
// GetByKey returns the item stored under the key, or sets exists=false.
|
||||
func (c *ExpirationCache) GetByKey(key string) (interface{}, bool, error) {
|
||||
obj, exists := c.getOrExpire(key)
|
||||
return obj, exists, nil
|
||||
}
|
||||
|
||||
// Get returns unexpired items. It purges the cache of expired items in the
|
||||
// process.
|
||||
func (c *ExpirationCache) Get(obj interface{}) (interface{}, bool, error) {
|
||||
key, err := c.keyFunc(obj)
|
||||
if err != nil {
|
||||
return nil, false, KeyError{obj, err}
|
||||
}
|
||||
obj, exists := c.getOrExpire(key)
|
||||
return obj, exists, nil
|
||||
}
|
||||
|
||||
// List retrieves a list of unexpired items. It purges the cache of expired
|
||||
// items in the process.
|
||||
func (c *ExpirationCache) List() []interface{} {
|
||||
items := c.cacheStorage.List()
|
||||
|
||||
list := make([]interface{}, 0, len(items))
|
||||
for _, item := range items {
|
||||
obj := item.(*timestampedEntry).obj
|
||||
if key, err := c.keyFunc(obj); err != nil {
|
||||
list = append(list, obj)
|
||||
} else if obj, exists := c.getOrExpire(key); exists {
|
||||
list = append(list, obj)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// ListKeys returns a list of all keys in the expiration cache.
|
||||
func (c *ExpirationCache) ListKeys() []string {
|
||||
return c.cacheStorage.ListKeys()
|
||||
}
|
||||
|
||||
// Add timestamps an item and inserts it into the cache, overwriting entries
|
||||
// that might exist under the same key.
|
||||
func (c *ExpirationCache) Add(obj interface{}) error {
|
||||
key, err := c.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
c.cacheStorage.Add(key, ×tampedEntry{obj, c.clock.Now()})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update has not been implemented yet for lack of a use case, so this method
|
||||
// simply calls `Add`. This effectively refreshes the timestamp.
|
||||
func (c *ExpirationCache) Update(obj interface{}) error {
|
||||
return c.Add(obj)
|
||||
}
|
||||
|
||||
// Delete removes an item from the cache.
|
||||
func (c *ExpirationCache) Delete(obj interface{}) error {
|
||||
key, err := c.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
c.cacheStorage.Delete(key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Replace will convert all items in the given list to TimestampedEntries
|
||||
// before attempting the replace operation. The replace operation will
|
||||
// delete the contents of the ExpirationCache `c`.
|
||||
func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error {
|
||||
items := map[string]interface{}{}
|
||||
ts := c.clock.Now()
|
||||
for _, item := range list {
|
||||
key, err := c.keyFunc(item)
|
||||
if err != nil {
|
||||
return KeyError{item, err}
|
||||
}
|
||||
items[key] = ×tampedEntry{item, ts}
|
||||
}
|
||||
c.cacheStorage.Replace(items, resourceVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewTTLStore creates and returns a ExpirationCache with a TTLPolicy
|
||||
func NewTTLStore(keyFunc KeyFunc, ttl time.Duration) Store {
|
||||
return &ExpirationCache{
|
||||
cacheStorage: NewThreadSafeStore(Indexers{}, Indices{}),
|
||||
keyFunc: keyFunc,
|
||||
clock: util.RealClock{},
|
||||
expirationPolicy: &TTLPolicy{ttl, util.RealClock{}},
|
||||
}
|
||||
}
|
||||
53
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_fakes.go
generated
vendored
Normal file
53
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_fakes.go
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
||||
type fakeThreadSafeMap struct {
|
||||
ThreadSafeStore
|
||||
deletedKeys chan<- string
|
||||
}
|
||||
|
||||
func (c *fakeThreadSafeMap) Delete(key string) {
|
||||
if c.deletedKeys != nil {
|
||||
c.deletedKeys <- key
|
||||
}
|
||||
}
|
||||
|
||||
type FakeExpirationPolicy struct {
|
||||
NeverExpire sets.String
|
||||
RetrieveKeyFunc KeyFunc
|
||||
}
|
||||
|
||||
func (p *FakeExpirationPolicy) IsExpired(obj *timestampedEntry) bool {
|
||||
key, _ := p.RetrieveKeyFunc(obj)
|
||||
return !p.NeverExpire.Has(key)
|
||||
}
|
||||
|
||||
func NewFakeExpirationStore(keyFunc KeyFunc, deletedKeys chan<- string, expirationPolicy ExpirationPolicy, cacheClock util.Clock) Store {
|
||||
cacheStorage := NewThreadSafeStore(Indexers{}, Indices{})
|
||||
return &ExpirationCache{
|
||||
cacheStorage: &fakeThreadSafeMap{cacheStorage, deletedKeys},
|
||||
keyFunc: keyFunc,
|
||||
clock: cacheClock,
|
||||
expirationPolicy: expirationPolicy,
|
||||
}
|
||||
}
|
||||
136
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_test.go
generated
vendored
Normal file
136
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/expiration_cache_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
)
|
||||
|
||||
func TestTTLExpirationBasic(t *testing.T) {
|
||||
testObj := testStoreObject{id: "foo", val: "bar"}
|
||||
deleteChan := make(chan string)
|
||||
ttlStore := NewFakeExpirationStore(
|
||||
testStoreKeyFunc, deleteChan,
|
||||
&FakeExpirationPolicy{
|
||||
NeverExpire: sets.NewString(),
|
||||
RetrieveKeyFunc: func(obj interface{}) (string, error) {
|
||||
return obj.(*timestampedEntry).obj.(testStoreObject).id, nil
|
||||
},
|
||||
},
|
||||
util.RealClock{},
|
||||
)
|
||||
err := ttlStore.Add(testObj)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to add obj %#v", testObj)
|
||||
}
|
||||
item, exists, err := ttlStore.Get(testObj)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to get from store, %v", err)
|
||||
}
|
||||
if exists || item != nil {
|
||||
t.Errorf("Got unexpected item %#v", item)
|
||||
}
|
||||
key, _ := testStoreKeyFunc(testObj)
|
||||
select {
|
||||
case delKey := <-deleteChan:
|
||||
if delKey != key {
|
||||
t.Errorf("Unexpected delete for key %s", key)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Errorf("Unexpected timeout waiting on delete")
|
||||
}
|
||||
close(deleteChan)
|
||||
}
|
||||
|
||||
func TestTTLList(t *testing.T) {
|
||||
testObjs := []testStoreObject{
|
||||
{id: "foo", val: "bar"},
|
||||
{id: "foo1", val: "bar1"},
|
||||
{id: "foo2", val: "bar2"},
|
||||
}
|
||||
expireKeys := sets.NewString(testObjs[0].id, testObjs[2].id)
|
||||
deleteChan := make(chan string)
|
||||
defer close(deleteChan)
|
||||
|
||||
ttlStore := NewFakeExpirationStore(
|
||||
testStoreKeyFunc, deleteChan,
|
||||
&FakeExpirationPolicy{
|
||||
NeverExpire: sets.NewString(testObjs[1].id),
|
||||
RetrieveKeyFunc: func(obj interface{}) (string, error) {
|
||||
return obj.(*timestampedEntry).obj.(testStoreObject).id, nil
|
||||
},
|
||||
},
|
||||
util.RealClock{},
|
||||
)
|
||||
for _, obj := range testObjs {
|
||||
err := ttlStore.Add(obj)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to add obj %#v", obj)
|
||||
}
|
||||
}
|
||||
listObjs := ttlStore.List()
|
||||
if len(listObjs) != 1 || !reflect.DeepEqual(listObjs[0], testObjs[1]) {
|
||||
t.Errorf("List returned unexpected results %#v", listObjs)
|
||||
}
|
||||
|
||||
// Make sure all our deletes come through in an acceptable rate (1/100ms)
|
||||
for expireKeys.Len() != 0 {
|
||||
select {
|
||||
case delKey := <-deleteChan:
|
||||
if !expireKeys.Has(delKey) {
|
||||
t.Errorf("Unexpected delete for key %s", delKey)
|
||||
}
|
||||
expireKeys.Delete(delKey)
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Errorf("Unexpected timeout waiting on delete")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTTLPolicy(t *testing.T) {
|
||||
fakeTime := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
|
||||
ttl := 30 * time.Second
|
||||
exactlyOnTTL := fakeTime.Add(-ttl)
|
||||
expiredTime := fakeTime.Add(-(ttl + 1))
|
||||
|
||||
policy := TTLPolicy{ttl, util.NewFakeClock(fakeTime)}
|
||||
fakeTimestampedEntry := ×tampedEntry{obj: struct{}{}, timestamp: exactlyOnTTL}
|
||||
if policy.IsExpired(fakeTimestampedEntry) {
|
||||
t.Errorf("TTL cache should not expire entries exactly on ttl")
|
||||
}
|
||||
fakeTimestampedEntry.timestamp = fakeTime
|
||||
if policy.IsExpired(fakeTimestampedEntry) {
|
||||
t.Errorf("TTL Cache should not expire entries before ttl")
|
||||
}
|
||||
fakeTimestampedEntry.timestamp = expiredTime
|
||||
if !policy.IsExpired(fakeTimestampedEntry) {
|
||||
t.Errorf("TTL Cache should expire entries older than ttl")
|
||||
}
|
||||
for _, ttl = range []time.Duration{0, -1} {
|
||||
policy.Ttl = ttl
|
||||
if policy.IsExpired(fakeTimestampedEntry) {
|
||||
t.Errorf("TTL policy should only expire entries when initialized with a ttl > 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
254
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/fifo.go
generated
vendored
Normal file
254
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/fifo.go
generated
vendored
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Queue is exactly like a Store, but has a Pop() method too.
|
||||
type Queue interface {
|
||||
Store
|
||||
|
||||
// Pop blocks until it has something to return.
|
||||
Pop() interface{}
|
||||
|
||||
// AddIfNotPresent adds a value previously
|
||||
// returned by Pop back into the queue as long
|
||||
// as nothing else (presumably more recent)
|
||||
// has since been added.
|
||||
AddIfNotPresent(interface{}) error
|
||||
|
||||
// Return true if the first batch of items has been popped
|
||||
HasSynced() bool
|
||||
}
|
||||
|
||||
// FIFO receives adds and updates from a Reflector, and puts them in a queue for
|
||||
// FIFO order processing. If multiple adds/updates of a single item happen while
|
||||
// an item is in the queue before it has been processed, it will only be
|
||||
// processed once, and when it is processed, the most recent version will be
|
||||
// processed. This can't be done with a channel.
|
||||
//
|
||||
// FIFO solves this use case:
|
||||
// * You want to process every object (exactly) once.
|
||||
// * You want to process the most recent version of the object when you process it.
|
||||
// * You do not want to process deleted objects, they should be removed from the queue.
|
||||
// * You do not want to periodically reprocess objects.
|
||||
// Compare with DeltaFIFO for other use cases.
|
||||
type FIFO struct {
|
||||
lock sync.RWMutex
|
||||
cond sync.Cond
|
||||
// We depend on the property that items in the set are in the queue and vice versa.
|
||||
items map[string]interface{}
|
||||
queue []string
|
||||
|
||||
// populated is true if the first batch of items inserted by Replace() has been populated
|
||||
// or Delete/Add/Update was called first.
|
||||
populated bool
|
||||
// initialPopulationCount is the number of items inserted by the first call of Replace()
|
||||
initialPopulationCount int
|
||||
|
||||
// keyFunc is used to make the key used for queued item insertion and retrieval, and
|
||||
// should be deterministic.
|
||||
keyFunc KeyFunc
|
||||
}
|
||||
|
||||
var (
|
||||
_ = Queue(&FIFO{}) // FIFO is a Queue
|
||||
)
|
||||
|
||||
// Return true if an Add/Update/Delete/AddIfNotPresent are called first,
|
||||
// or an Update called first but the first batch of items inserted by Replace() has been popped
|
||||
func (f *FIFO) HasSynced() bool {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
return f.populated && f.initialPopulationCount == 0
|
||||
}
|
||||
|
||||
// Add inserts an item, and puts it in the queue. The item is only enqueued
|
||||
// if it doesn't already exist in the set.
|
||||
func (f *FIFO) Add(obj interface{}) error {
|
||||
id, err := f.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.populated = true
|
||||
if _, exists := f.items[id]; !exists {
|
||||
f.queue = append(f.queue, id)
|
||||
}
|
||||
f.items[id] = obj
|
||||
f.cond.Broadcast()
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddIfNotPresent inserts an item, and puts it in the queue. If the item is already
|
||||
// present in the set, it is neither enqueued nor added to the set.
|
||||
//
|
||||
// This is useful in a single producer/consumer scenario so that the consumer can
|
||||
// safely retry items without contending with the producer and potentially enqueueing
|
||||
// stale items.
|
||||
func (f *FIFO) AddIfNotPresent(obj interface{}) error {
|
||||
id, err := f.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.populated = true
|
||||
if _, exists := f.items[id]; exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.queue = append(f.queue, id)
|
||||
f.items[id] = obj
|
||||
f.cond.Broadcast()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update is the same as Add in this implementation.
|
||||
func (f *FIFO) Update(obj interface{}) error {
|
||||
return f.Add(obj)
|
||||
}
|
||||
|
||||
// Delete removes an item. It doesn't add it to the queue, because
|
||||
// this implementation assumes the consumer only cares about the objects,
|
||||
// not the order in which they were created/added.
|
||||
func (f *FIFO) Delete(obj interface{}) error {
|
||||
id, err := f.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.populated = true
|
||||
delete(f.items, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// List returns a list of all the items.
|
||||
func (f *FIFO) List() []interface{} {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
list := make([]interface{}, 0, len(f.items))
|
||||
for _, item := range f.items {
|
||||
list = append(list, item)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// ListKeys returns a list of all the keys of the objects currently
|
||||
// in the FIFO.
|
||||
func (f *FIFO) ListKeys() []string {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
list := make([]string, 0, len(f.items))
|
||||
for key := range f.items {
|
||||
list = append(list, key)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// Get returns the requested item, or sets exists=false.
|
||||
func (f *FIFO) Get(obj interface{}) (item interface{}, exists bool, err error) {
|
||||
key, err := f.keyFunc(obj)
|
||||
if err != nil {
|
||||
return nil, false, KeyError{obj, err}
|
||||
}
|
||||
return f.GetByKey(key)
|
||||
}
|
||||
|
||||
// GetByKey returns the requested item, or sets exists=false.
|
||||
func (f *FIFO) GetByKey(key string) (item interface{}, exists bool, err error) {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
item, exists = f.items[key]
|
||||
return item, exists, nil
|
||||
}
|
||||
|
||||
// Pop waits until an item is ready and returns it. If multiple items are
|
||||
// ready, they are returned in the order in which they were added/updated.
|
||||
// The item is removed from the queue (and the store) before it is returned,
|
||||
// so if you don't successfully process it, you need to add it back with
|
||||
// AddIfNotPresent().
|
||||
func (f *FIFO) Pop() interface{} {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
for {
|
||||
for len(f.queue) == 0 {
|
||||
f.cond.Wait()
|
||||
}
|
||||
id := f.queue[0]
|
||||
f.queue = f.queue[1:]
|
||||
if f.initialPopulationCount > 0 {
|
||||
f.initialPopulationCount--
|
||||
}
|
||||
item, ok := f.items[id]
|
||||
if !ok {
|
||||
// Item may have been deleted subsequently.
|
||||
continue
|
||||
}
|
||||
delete(f.items, id)
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
// Replace will delete the contents of 'f', using instead the given map.
|
||||
// 'f' takes ownership of the map, you should not reference the map again
|
||||
// after calling this function. f's queue is reset, too; upon return, it
|
||||
// will contain the items in the map, in no particular order.
|
||||
func (f *FIFO) Replace(list []interface{}, resourceVersion string) error {
|
||||
items := map[string]interface{}{}
|
||||
for _, item := range list {
|
||||
key, err := f.keyFunc(item)
|
||||
if err != nil {
|
||||
return KeyError{item, err}
|
||||
}
|
||||
items[key] = item
|
||||
}
|
||||
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
if !f.populated {
|
||||
f.populated = true
|
||||
f.initialPopulationCount = len(items)
|
||||
}
|
||||
|
||||
f.items = items
|
||||
f.queue = f.queue[:0]
|
||||
for id := range items {
|
||||
f.queue = append(f.queue, id)
|
||||
}
|
||||
if len(f.queue) > 0 {
|
||||
f.cond.Broadcast()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewFIFO returns a Store which can be used to queue up items to
|
||||
// process.
|
||||
func NewFIFO(keyFunc KeyFunc) *FIFO {
|
||||
f := &FIFO{
|
||||
items: map[string]interface{}{},
|
||||
queue: []string{},
|
||||
keyFunc: keyFunc,
|
||||
}
|
||||
f.cond.L = &f.lock
|
||||
return f
|
||||
}
|
||||
235
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/fifo_test.go
generated
vendored
Normal file
235
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/fifo_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func testFifoObjectKeyFunc(obj interface{}) (string, error) {
|
||||
return obj.(testFifoObject).name, nil
|
||||
}
|
||||
|
||||
type testFifoObject struct {
|
||||
name string
|
||||
val interface{}
|
||||
}
|
||||
|
||||
func mkFifoObj(name string, val interface{}) testFifoObject {
|
||||
return testFifoObject{name: name, val: val}
|
||||
}
|
||||
|
||||
func TestFIFO_basic(t *testing.T) {
|
||||
f := NewFIFO(testFifoObjectKeyFunc)
|
||||
const amount = 500
|
||||
go func() {
|
||||
for i := 0; i < amount; i++ {
|
||||
f.Add(mkFifoObj(string([]rune{'a', rune(i)}), i+1))
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for u := uint64(0); u < amount; u++ {
|
||||
f.Add(mkFifoObj(string([]rune{'b', rune(u)}), u+1))
|
||||
}
|
||||
}()
|
||||
|
||||
lastInt := int(0)
|
||||
lastUint := uint64(0)
|
||||
for i := 0; i < amount*2; i++ {
|
||||
switch obj := f.Pop().(testFifoObject).val.(type) {
|
||||
case int:
|
||||
if obj <= lastInt {
|
||||
t.Errorf("got %v (int) out of order, last was %v", obj, lastInt)
|
||||
}
|
||||
lastInt = obj
|
||||
case uint64:
|
||||
if obj <= lastUint {
|
||||
t.Errorf("got %v (uint) out of order, last was %v", obj, lastUint)
|
||||
} else {
|
||||
lastUint = obj
|
||||
}
|
||||
default:
|
||||
t.Fatalf("unexpected type %#v", obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFIFO_addUpdate(t *testing.T) {
|
||||
f := NewFIFO(testFifoObjectKeyFunc)
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Update(mkFifoObj("foo", 15))
|
||||
|
||||
if e, a := []interface{}{mkFifoObj("foo", 15)}, f.List(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %+v, got %+v", e, a)
|
||||
}
|
||||
if e, a := []string{"foo"}, f.ListKeys(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %+v, got %+v", e, a)
|
||||
}
|
||||
|
||||
got := make(chan testFifoObject, 2)
|
||||
go func() {
|
||||
for {
|
||||
got <- f.Pop().(testFifoObject)
|
||||
}
|
||||
}()
|
||||
|
||||
first := <-got
|
||||
if e, a := 15, first.val; e != a {
|
||||
t.Errorf("Didn't get updated value (%v), got %v", e, a)
|
||||
}
|
||||
select {
|
||||
case unexpected := <-got:
|
||||
t.Errorf("Got second value %v", unexpected.val)
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
_, exists, _ := f.Get(mkFifoObj("foo", ""))
|
||||
if exists {
|
||||
t.Errorf("item did not get removed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFIFO_addReplace(t *testing.T) {
|
||||
f := NewFIFO(testFifoObjectKeyFunc)
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Replace([]interface{}{mkFifoObj("foo", 15)}, "15")
|
||||
got := make(chan testFifoObject, 2)
|
||||
go func() {
|
||||
for {
|
||||
got <- f.Pop().(testFifoObject)
|
||||
}
|
||||
}()
|
||||
|
||||
first := <-got
|
||||
if e, a := 15, first.val; e != a {
|
||||
t.Errorf("Didn't get updated value (%v), got %v", e, a)
|
||||
}
|
||||
select {
|
||||
case unexpected := <-got:
|
||||
t.Errorf("Got second value %v", unexpected.val)
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
_, exists, _ := f.Get(mkFifoObj("foo", ""))
|
||||
if exists {
|
||||
t.Errorf("item did not get removed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFIFO_detectLineJumpers(t *testing.T) {
|
||||
f := NewFIFO(testFifoObjectKeyFunc)
|
||||
|
||||
f.Add(mkFifoObj("foo", 10))
|
||||
f.Add(mkFifoObj("bar", 1))
|
||||
f.Add(mkFifoObj("foo", 11))
|
||||
f.Add(mkFifoObj("foo", 13))
|
||||
f.Add(mkFifoObj("zab", 30))
|
||||
|
||||
if e, a := 13, f.Pop().(testFifoObject).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
f.Add(mkFifoObj("foo", 14)) // ensure foo doesn't jump back in line
|
||||
|
||||
if e, a := 1, f.Pop().(testFifoObject).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
if e, a := 30, f.Pop().(testFifoObject).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
|
||||
if e, a := 14, f.Pop().(testFifoObject).val; a != e {
|
||||
t.Fatalf("expected %d, got %d", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFIFO_addIfNotPresent(t *testing.T) {
|
||||
f := NewFIFO(testFifoObjectKeyFunc)
|
||||
|
||||
f.Add(mkFifoObj("a", 1))
|
||||
f.Add(mkFifoObj("b", 2))
|
||||
f.AddIfNotPresent(mkFifoObj("b", 3))
|
||||
f.AddIfNotPresent(mkFifoObj("c", 4))
|
||||
|
||||
if e, a := 3, len(f.items); a != e {
|
||||
t.Fatalf("expected queue length %d, got %d", e, a)
|
||||
}
|
||||
|
||||
expectedValues := []int{1, 2, 4}
|
||||
for _, expected := range expectedValues {
|
||||
if actual := f.Pop().(testFifoObject).val; actual != expected {
|
||||
t.Fatalf("expected value %d, got %d", expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFIFO_HasSynced(t *testing.T) {
|
||||
tests := []struct {
|
||||
actions []func(f *FIFO)
|
||||
expectedSynced bool
|
||||
}{
|
||||
{
|
||||
actions: []func(f *FIFO){},
|
||||
expectedSynced: false,
|
||||
},
|
||||
{
|
||||
actions: []func(f *FIFO){
|
||||
func(f *FIFO) { f.Add(mkFifoObj("a", 1)) },
|
||||
},
|
||||
expectedSynced: true,
|
||||
},
|
||||
{
|
||||
actions: []func(f *FIFO){
|
||||
func(f *FIFO) { f.Replace([]interface{}{}, "0") },
|
||||
},
|
||||
expectedSynced: true,
|
||||
},
|
||||
{
|
||||
actions: []func(f *FIFO){
|
||||
func(f *FIFO) { f.Replace([]interface{}{mkFifoObj("a", 1), mkFifoObj("b", 2)}, "0") },
|
||||
},
|
||||
expectedSynced: false,
|
||||
},
|
||||
{
|
||||
actions: []func(f *FIFO){
|
||||
func(f *FIFO) { f.Replace([]interface{}{mkFifoObj("a", 1), mkFifoObj("b", 2)}, "0") },
|
||||
func(f *FIFO) { f.Pop() },
|
||||
},
|
||||
expectedSynced: false,
|
||||
},
|
||||
{
|
||||
actions: []func(f *FIFO){
|
||||
func(f *FIFO) { f.Replace([]interface{}{mkFifoObj("a", 1), mkFifoObj("b", 2)}, "0") },
|
||||
func(f *FIFO) { f.Pop() },
|
||||
func(f *FIFO) { f.Pop() },
|
||||
},
|
||||
expectedSynced: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
f := NewFIFO(testFifoObjectKeyFunc)
|
||||
|
||||
for _, action := range test.actions {
|
||||
action(f)
|
||||
}
|
||||
if e, a := test.expectedSynced, f.HasSynced(); a != e {
|
||||
t.Errorf("test case %v failed, expected: %v , got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/index.go
generated
vendored
Normal file
72
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/index.go
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
||||
// Indexer is a storage interface that lets you list objects using multiple indexing functions
|
||||
type Indexer interface {
|
||||
Store
|
||||
// Retrieve list of objects that match on the named indexing function
|
||||
Index(indexName string, obj interface{}) ([]interface{}, error)
|
||||
// ListIndexFuncValues returns the list of generated values of an Index func
|
||||
ListIndexFuncValues(indexName string) []string
|
||||
// ByIndex lists object that match on the named indexing function with the exact key
|
||||
ByIndex(indexName, indexKey string) ([]interface{}, error)
|
||||
}
|
||||
|
||||
// IndexFunc knows how to provide an indexed value for an object.
|
||||
type IndexFunc func(obj interface{}) ([]string, error)
|
||||
|
||||
// IndexFuncToKeyFuncAdapter adapts an indexFunc to a keyFunc. This is only useful if your index function returns
|
||||
// unique values for every object. This is conversion can create errors when more than one key is found. You
|
||||
// should prefer to make proper key and index functions.
|
||||
func IndexFuncToKeyFuncAdapter(indexFunc IndexFunc) KeyFunc {
|
||||
return func(obj interface{}) (string, error) {
|
||||
indexKeys, err := indexFunc(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(indexKeys) > 1 {
|
||||
return "", fmt.Errorf("too many keys: %v", indexKeys)
|
||||
}
|
||||
return indexKeys[0], nil
|
||||
}
|
||||
}
|
||||
|
||||
// MetaNamespaceIndexFunc is a default index function that indexes based on an object's namespace
|
||||
func MetaNamespaceIndexFunc(obj interface{}) ([]string, error) {
|
||||
meta, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return []string{""}, fmt.Errorf("object has no meta: %v", err)
|
||||
}
|
||||
return []string{meta.GetNamespace()}, nil
|
||||
}
|
||||
|
||||
// Index maps the indexed value to a set of keys in the store that match on that value
|
||||
type Index map[string]sets.String
|
||||
|
||||
// Indexers maps a name to a IndexFunc
|
||||
type Indexers map[string]IndexFunc
|
||||
|
||||
// Indices maps a name to an Index
|
||||
type Indices map[string]Index
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/index_test.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/index_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func testIndexFunc(obj interface{}) ([]string, error) {
|
||||
pod := obj.(*api.Pod)
|
||||
return []string{pod.Labels["foo"]}, nil
|
||||
}
|
||||
|
||||
func TestGetIndexFuncValues(t *testing.T) {
|
||||
index := NewIndexer(MetaNamespaceKeyFunc, Indexers{"testmodes": testIndexFunc})
|
||||
|
||||
pod1 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "one", Labels: map[string]string{"foo": "bar"}}}
|
||||
pod2 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "two", Labels: map[string]string{"foo": "bar"}}}
|
||||
pod3 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "tre", Labels: map[string]string{"foo": "biz"}}}
|
||||
|
||||
index.Add(pod1)
|
||||
index.Add(pod2)
|
||||
index.Add(pod3)
|
||||
|
||||
keys := index.ListIndexFuncValues("testmodes")
|
||||
if len(keys) != 2 {
|
||||
t.Errorf("Expected 2 keys but got %v", len(keys))
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
if key != "bar" && key != "biz" {
|
||||
t.Errorf("Expected only 'bar' or 'biz' but got %s", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testUsersIndexFunc(obj interface{}) ([]string, error) {
|
||||
pod := obj.(*api.Pod)
|
||||
usersString := pod.Annotations["users"]
|
||||
|
||||
return strings.Split(usersString, ","), nil
|
||||
}
|
||||
|
||||
func TestMultiIndexKeys(t *testing.T) {
|
||||
index := NewIndexer(MetaNamespaceKeyFunc, Indexers{"byUser": testUsersIndexFunc})
|
||||
|
||||
pod1 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "one", Annotations: map[string]string{"users": "ernie,bert"}}}
|
||||
pod2 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "two", Annotations: map[string]string{"users": "bert,oscar"}}}
|
||||
pod3 := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "tre", Annotations: map[string]string{"users": "ernie,elmo"}}}
|
||||
|
||||
index.Add(pod1)
|
||||
index.Add(pod2)
|
||||
index.Add(pod3)
|
||||
|
||||
erniePods, err := index.ByIndex("byUser", "ernie")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if len(erniePods) != 2 {
|
||||
t.Errorf("Expected 2 pods but got %v", len(erniePods))
|
||||
}
|
||||
|
||||
bertPods, err := index.ByIndex("byUser", "bert")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if len(bertPods) != 2 {
|
||||
t.Errorf("Expected 2 pods but got %v", len(bertPods))
|
||||
}
|
||||
|
||||
oscarPods, err := index.ByIndex("byUser", "oscar")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if len(oscarPods) != 1 {
|
||||
t.Errorf("Expected 1 pods but got %v", len(erniePods))
|
||||
}
|
||||
|
||||
ernieAndBertKeys, err := index.Index("byUser", pod1)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if len(ernieAndBertKeys) != 3 {
|
||||
t.Errorf("Expected 3 pods but got %v", len(ernieAndBertKeys))
|
||||
}
|
||||
|
||||
index.Delete(pod3)
|
||||
erniePods, err = index.ByIndex("byUser", "ernie")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if len(erniePods) != 1 {
|
||||
t.Errorf("Expected 1 pods but got %v", len(erniePods))
|
||||
}
|
||||
elmoPods, err := index.ByIndex("byUser", "elmo")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if len(elmoPods) != 0 {
|
||||
t.Errorf("Expected 0 pods but got %v", len(elmoPods))
|
||||
}
|
||||
|
||||
obj, err := api.Scheme.DeepCopy(pod2)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
copyOfPod2 := obj.(*api.Pod)
|
||||
copyOfPod2.Annotations["users"] = "oscar"
|
||||
index.Update(copyOfPod2)
|
||||
bertPods, err = index.ByIndex("byUser", "bert")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if len(bertPods) != 1 {
|
||||
t.Errorf("Expected 1 pods but got %v", len(bertPods))
|
||||
}
|
||||
|
||||
}
|
||||
558
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers.go
generated
vendored
Normal file
558
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers.go
generated
vendored
Normal file
|
|
@ -0,0 +1,558 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
)
|
||||
|
||||
// TODO: generate these classes and methods for all resources of interest using
|
||||
// a script. Can use "go generate" once 1.4 is supported by all users.
|
||||
|
||||
// StoreToPodLister makes a Store have the List method of the client.PodInterface
|
||||
// The Store must contain (only) Pods.
|
||||
//
|
||||
// Example:
|
||||
// s := cache.NewStore()
|
||||
// lw := cache.ListWatch{Client: c, FieldSelector: sel, Resource: "pods"}
|
||||
// r := cache.NewReflector(lw, &api.Pod{}, s).Run()
|
||||
// l := StoreToPodLister{s}
|
||||
// l.List()
|
||||
type StoreToPodLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// Please note that selector is filtering among the pods that have gotten into
|
||||
// the store; there may have been some filtering that already happened before
|
||||
// that.
|
||||
//
|
||||
// TODO: converge on the interface in pkg/client.
|
||||
func (s *StoreToPodLister) List(selector labels.Selector) (pods []*api.Pod, err error) {
|
||||
// TODO: it'd be great to just call
|
||||
// s.Pods(api.NamespaceAll).List(selector), however then we'd have to
|
||||
// remake the list.Items as a []*api.Pod. So leave this separate for
|
||||
// now.
|
||||
for _, m := range s.Store.List() {
|
||||
pod := m.(*api.Pod)
|
||||
if selector.Matches(labels.Set(pod.Labels)) {
|
||||
pods = append(pods, pod)
|
||||
}
|
||||
}
|
||||
return pods, nil
|
||||
}
|
||||
|
||||
// Pods is taking baby steps to be more like the api in pkg/client
|
||||
func (s *StoreToPodLister) Pods(namespace string) storePodsNamespacer {
|
||||
return storePodsNamespacer{s.Store, namespace}
|
||||
}
|
||||
|
||||
type storePodsNamespacer struct {
|
||||
store Store
|
||||
namespace string
|
||||
}
|
||||
|
||||
// Please note that selector is filtering among the pods that have gotten into
|
||||
// the store; there may have been some filtering that already happened before
|
||||
// that.
|
||||
func (s storePodsNamespacer) List(selector labels.Selector) (pods api.PodList, err error) {
|
||||
list := api.PodList{}
|
||||
for _, m := range s.store.List() {
|
||||
pod := m.(*api.Pod)
|
||||
if s.namespace == api.NamespaceAll || s.namespace == pod.Namespace {
|
||||
if selector.Matches(labels.Set(pod.Labels)) {
|
||||
list.Items = append(list.Items, *pod)
|
||||
}
|
||||
}
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// Exists returns true if a pod matching the namespace/name of the given pod exists in the store.
|
||||
func (s *StoreToPodLister) Exists(pod *api.Pod) (bool, error) {
|
||||
_, exists, err := s.Store.Get(pod)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// NodeConditionPredicate is a function that indicates whether the given node's conditions meet
|
||||
// some set of criteria defined by the function.
|
||||
type NodeConditionPredicate func(node api.Node) bool
|
||||
|
||||
// StoreToNodeLister makes a Store have the List method of the client.NodeInterface
|
||||
// The Store must contain (only) Nodes.
|
||||
type StoreToNodeLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
func (s *StoreToNodeLister) List() (machines api.NodeList, err error) {
|
||||
for _, m := range s.Store.List() {
|
||||
machines.Items = append(machines.Items, *(m.(*api.Node)))
|
||||
}
|
||||
return machines, nil
|
||||
}
|
||||
|
||||
// NodeCondition returns a storeToNodeConditionLister
|
||||
func (s *StoreToNodeLister) NodeCondition(predicate NodeConditionPredicate) storeToNodeConditionLister {
|
||||
// TODO: Move this filtering server side. Currently our selectors don't facilitate searching through a list so we
|
||||
// have the reflector filter out the Unschedulable field and sift through node conditions in the lister.
|
||||
return storeToNodeConditionLister{s.Store, predicate}
|
||||
}
|
||||
|
||||
// storeToNodeConditionLister filters and returns nodes matching the given type and status from the store.
|
||||
type storeToNodeConditionLister struct {
|
||||
store Store
|
||||
predicate NodeConditionPredicate
|
||||
}
|
||||
|
||||
// List returns a list of nodes that match the conditions defined by the predicate functions in the storeToNodeConditionLister.
|
||||
func (s storeToNodeConditionLister) List() (nodes api.NodeList, err error) {
|
||||
for _, m := range s.store.List() {
|
||||
node := *m.(*api.Node)
|
||||
if s.predicate(node) {
|
||||
nodes.Items = append(nodes.Items, node)
|
||||
} else {
|
||||
glog.V(5).Infof("Node %s matches none of the conditions", node.Name)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StoreToReplicationControllerLister gives a store List and Exists methods. The store must contain only ReplicationControllers.
|
||||
type StoreToReplicationControllerLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// Exists checks if the given rc exists in the store.
|
||||
func (s *StoreToReplicationControllerLister) Exists(controller *api.ReplicationController) (bool, error) {
|
||||
_, exists, err := s.Store.Get(controller)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// StoreToReplicationControllerLister lists all controllers in the store.
|
||||
// TODO: converge on the interface in pkg/client
|
||||
func (s *StoreToReplicationControllerLister) List() (controllers []api.ReplicationController, err error) {
|
||||
for _, c := range s.Store.List() {
|
||||
controllers = append(controllers, *(c.(*api.ReplicationController)))
|
||||
}
|
||||
return controllers, nil
|
||||
}
|
||||
|
||||
func (s *StoreToReplicationControllerLister) ReplicationControllers(namespace string) storeReplicationControllersNamespacer {
|
||||
return storeReplicationControllersNamespacer{s.Store, namespace}
|
||||
}
|
||||
|
||||
type storeReplicationControllersNamespacer struct {
|
||||
store Store
|
||||
namespace string
|
||||
}
|
||||
|
||||
func (s storeReplicationControllersNamespacer) List(selector labels.Selector) (controllers []api.ReplicationController, err error) {
|
||||
for _, c := range s.store.List() {
|
||||
rc := *(c.(*api.ReplicationController))
|
||||
if s.namespace == api.NamespaceAll || s.namespace == rc.Namespace {
|
||||
if selector.Matches(labels.Set(rc.Labels)) {
|
||||
controllers = append(controllers, rc)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetPodControllers returns a list of replication controllers managing a pod. Returns an error only if no matching controllers are found.
|
||||
func (s *StoreToReplicationControllerLister) GetPodControllers(pod *api.Pod) (controllers []api.ReplicationController, err error) {
|
||||
var selector labels.Selector
|
||||
var rc api.ReplicationController
|
||||
|
||||
if len(pod.Labels) == 0 {
|
||||
err = fmt.Errorf("no controllers found for pod %v because it has no labels", pod.Name)
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range s.Store.List() {
|
||||
rc = *m.(*api.ReplicationController)
|
||||
if rc.Namespace != pod.Namespace {
|
||||
continue
|
||||
}
|
||||
labelSet := labels.Set(rc.Spec.Selector)
|
||||
selector = labels.Set(rc.Spec.Selector).AsSelector()
|
||||
|
||||
// If an rc with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||
if labelSet.AsSelector().Empty() || !selector.Matches(labels.Set(pod.Labels)) {
|
||||
continue
|
||||
}
|
||||
controllers = append(controllers, rc)
|
||||
}
|
||||
if len(controllers) == 0 {
|
||||
err = fmt.Errorf("could not find controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StoreToDeploymentLister gives a store List and Exists methods. The store must contain only Deployments.
|
||||
type StoreToDeploymentLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// Exists checks if the given deployment exists in the store.
|
||||
func (s *StoreToDeploymentLister) Exists(deployment *extensions.Deployment) (bool, error) {
|
||||
_, exists, err := s.Store.Get(deployment)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// StoreToDeploymentLister lists all deployments in the store.
|
||||
// TODO: converge on the interface in pkg/client
|
||||
func (s *StoreToDeploymentLister) List() (deployments []extensions.Deployment, err error) {
|
||||
for _, c := range s.Store.List() {
|
||||
deployments = append(deployments, *(c.(*extensions.Deployment)))
|
||||
}
|
||||
return deployments, nil
|
||||
}
|
||||
|
||||
// GetDeploymentsForReplicaSet returns a list of deployments managing a replica set. Returns an error only if no matching deployments are found.
|
||||
func (s *StoreToDeploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) (deployments []extensions.Deployment, err error) {
|
||||
var d extensions.Deployment
|
||||
|
||||
if len(rs.Labels) == 0 {
|
||||
err = fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
|
||||
for _, m := range s.Store.List() {
|
||||
d = *m.(*extensions.Deployment)
|
||||
if d.Namespace != rs.Namespace {
|
||||
continue
|
||||
}
|
||||
|
||||
selector, err := unversioned.LabelSelectorAsSelector(d.Spec.Selector)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
||||
}
|
||||
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
|
||||
continue
|
||||
}
|
||||
deployments = append(deployments, d)
|
||||
}
|
||||
if len(deployments) == 0 {
|
||||
err = fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StoreToReplicaSetLister gives a store List and Exists methods. The store must contain only ReplicaSets.
|
||||
type StoreToReplicaSetLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// Exists checks if the given ReplicaSet exists in the store.
|
||||
func (s *StoreToReplicaSetLister) Exists(rs *extensions.ReplicaSet) (bool, error) {
|
||||
_, exists, err := s.Store.Get(rs)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// List lists all ReplicaSets in the store.
|
||||
// TODO: converge on the interface in pkg/client
|
||||
func (s *StoreToReplicaSetLister) List() (rss []extensions.ReplicaSet, err error) {
|
||||
for _, rs := range s.Store.List() {
|
||||
rss = append(rss, *(rs.(*extensions.ReplicaSet)))
|
||||
}
|
||||
return rss, nil
|
||||
}
|
||||
|
||||
type storeReplicaSetsNamespacer struct {
|
||||
store Store
|
||||
namespace string
|
||||
}
|
||||
|
||||
func (s storeReplicaSetsNamespacer) List(selector labels.Selector) (rss []extensions.ReplicaSet, err error) {
|
||||
for _, c := range s.store.List() {
|
||||
rs := *(c.(*extensions.ReplicaSet))
|
||||
if s.namespace == api.NamespaceAll || s.namespace == rs.Namespace {
|
||||
if selector.Matches(labels.Set(rs.Labels)) {
|
||||
rss = append(rss, rs)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *StoreToReplicaSetLister) ReplicaSets(namespace string) storeReplicaSetsNamespacer {
|
||||
return storeReplicaSetsNamespacer{s.Store, namespace}
|
||||
}
|
||||
|
||||
// GetPodReplicaSets returns a list of ReplicaSets managing a pod. Returns an error only if no matching ReplicaSets are found.
|
||||
func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *api.Pod) (rss []extensions.ReplicaSet, err error) {
|
||||
var selector labels.Selector
|
||||
var rs extensions.ReplicaSet
|
||||
|
||||
if len(pod.Labels) == 0 {
|
||||
err = fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name)
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range s.Store.List() {
|
||||
rs = *m.(*extensions.ReplicaSet)
|
||||
if rs.Namespace != pod.Namespace {
|
||||
continue
|
||||
}
|
||||
selector, err = unversioned.LabelSelectorAsSelector(rs.Spec.Selector)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("invalid selector: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
|
||||
continue
|
||||
}
|
||||
rss = append(rss, rs)
|
||||
}
|
||||
if len(rss) == 0 {
|
||||
err = fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StoreToDaemonSetLister gives a store List and Exists methods. The store must contain only DaemonSets.
|
||||
type StoreToDaemonSetLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// Exists checks if the given daemon set exists in the store.
|
||||
func (s *StoreToDaemonSetLister) Exists(ds *extensions.DaemonSet) (bool, error) {
|
||||
_, exists, err := s.Store.Get(ds)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// List lists all daemon sets in the store.
|
||||
// TODO: converge on the interface in pkg/client
|
||||
func (s *StoreToDaemonSetLister) List() (dss extensions.DaemonSetList, err error) {
|
||||
for _, c := range s.Store.List() {
|
||||
dss.Items = append(dss.Items, *(c.(*extensions.DaemonSet)))
|
||||
}
|
||||
return dss, nil
|
||||
}
|
||||
|
||||
// GetPodDaemonSets returns a list of daemon sets managing a pod.
|
||||
// Returns an error if and only if no matching daemon sets are found.
|
||||
func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *api.Pod) (daemonSets []extensions.DaemonSet, err error) {
|
||||
var selector labels.Selector
|
||||
var daemonSet extensions.DaemonSet
|
||||
|
||||
if len(pod.Labels) == 0 {
|
||||
err = fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name)
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range s.Store.List() {
|
||||
daemonSet = *m.(*extensions.DaemonSet)
|
||||
if daemonSet.Namespace != pod.Namespace {
|
||||
continue
|
||||
}
|
||||
selector, err = unversioned.LabelSelectorAsSelector(daemonSet.Spec.Selector)
|
||||
if err != nil {
|
||||
// this should not happen if the DaemonSet passed validation
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
|
||||
continue
|
||||
}
|
||||
daemonSets = append(daemonSets, daemonSet)
|
||||
}
|
||||
if len(daemonSets) == 0 {
|
||||
err = fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StoreToServiceLister makes a Store that has the List method of the client.ServiceInterface
|
||||
// The Store must contain (only) Services.
|
||||
type StoreToServiceLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
func (s *StoreToServiceLister) List() (services api.ServiceList, err error) {
|
||||
for _, m := range s.Store.List() {
|
||||
services.Items = append(services.Items, *(m.(*api.Service)))
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
// TODO: Move this back to scheduler as a helper function that takes a Store,
|
||||
// rather than a method of StoreToServiceLister.
|
||||
func (s *StoreToServiceLister) GetPodServices(pod *api.Pod) (services []api.Service, err error) {
|
||||
var selector labels.Selector
|
||||
var service api.Service
|
||||
|
||||
for _, m := range s.Store.List() {
|
||||
service = *m.(*api.Service)
|
||||
// consider only services that are in the same namespace as the pod
|
||||
if service.Namespace != pod.Namespace {
|
||||
continue
|
||||
}
|
||||
if service.Spec.Selector == nil {
|
||||
// services with nil selectors match nothing, not everything.
|
||||
continue
|
||||
}
|
||||
selector = labels.Set(service.Spec.Selector).AsSelector()
|
||||
if selector.Matches(labels.Set(pod.Labels)) {
|
||||
services = append(services, service)
|
||||
}
|
||||
}
|
||||
if len(services) == 0 {
|
||||
err = fmt.Errorf("could not find service for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// StoreToEndpointsLister makes a Store that lists endpoints.
|
||||
type StoreToEndpointsLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// List lists all endpoints in the store.
|
||||
func (s *StoreToEndpointsLister) List() (services api.EndpointsList, err error) {
|
||||
for _, m := range s.Store.List() {
|
||||
services.Items = append(services.Items, *(m.(*api.Endpoints)))
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
// GetServiceEndpoints returns the endpoints of a service, matched on service name.
|
||||
func (s *StoreToEndpointsLister) GetServiceEndpoints(svc *api.Service) (ep api.Endpoints, err error) {
|
||||
for _, m := range s.Store.List() {
|
||||
ep = *m.(*api.Endpoints)
|
||||
if svc.Name == ep.Name && svc.Namespace == ep.Namespace {
|
||||
return ep, nil
|
||||
}
|
||||
}
|
||||
err = fmt.Errorf("could not find endpoints for service: %v", svc.Name)
|
||||
return
|
||||
}
|
||||
|
||||
// StoreToJobLister gives a store List and Exists methods. The store must contain only Jobs.
|
||||
type StoreToJobLister struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// Exists checks if the given job exists in the store.
|
||||
func (s *StoreToJobLister) Exists(job *extensions.Job) (bool, error) {
|
||||
_, exists, err := s.Store.Get(job)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// StoreToJobLister lists all jobs in the store.
|
||||
func (s *StoreToJobLister) List() (jobs extensions.JobList, err error) {
|
||||
for _, c := range s.Store.List() {
|
||||
jobs.Items = append(jobs.Items, *(c.(*extensions.Job)))
|
||||
}
|
||||
return jobs, nil
|
||||
}
|
||||
|
||||
// GetPodJobs returns a list of jobs managing a pod. Returns an error only if no matching jobs are found.
|
||||
func (s *StoreToJobLister) GetPodJobs(pod *api.Pod) (jobs []extensions.Job, err error) {
|
||||
var selector labels.Selector
|
||||
var job extensions.Job
|
||||
|
||||
if len(pod.Labels) == 0 {
|
||||
err = fmt.Errorf("no jobs found for pod %v because it has no labels", pod.Name)
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range s.Store.List() {
|
||||
job = *m.(*extensions.Job)
|
||||
if job.Namespace != pod.Namespace {
|
||||
continue
|
||||
}
|
||||
|
||||
selector, _ = unversioned.LabelSelectorAsSelector(job.Spec.Selector)
|
||||
if !selector.Matches(labels.Set(pod.Labels)) {
|
||||
continue
|
||||
}
|
||||
jobs = append(jobs, job)
|
||||
}
|
||||
if len(jobs) == 0 {
|
||||
err = fmt.Errorf("could not find jobs for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Typed wrapper around a store of PersistentVolumes
|
||||
type StoreToPVFetcher struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// GetPersistentVolumeInfo returns cached data for the PersistentVolume 'id'.
|
||||
func (s *StoreToPVFetcher) GetPersistentVolumeInfo(id string) (*api.PersistentVolume, error) {
|
||||
o, exists, err := s.Get(&api.PersistentVolume{ObjectMeta: api.ObjectMeta{Name: id}})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving PersistentVolume '%v' from cache: %v", id, err)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("PersistentVolume '%v' is not in cache", id)
|
||||
}
|
||||
|
||||
return o.(*api.PersistentVolume), nil
|
||||
}
|
||||
|
||||
// Typed wrapper around a store of PersistentVolumeClaims
|
||||
type StoreToPVCFetcher struct {
|
||||
Store
|
||||
}
|
||||
|
||||
// GetPersistentVolumeClaimInfo returns cached data for the PersistentVolumeClaim 'id'.
|
||||
func (s *StoreToPVCFetcher) GetPersistentVolumeClaimInfo(namespace string, id string) (*api.PersistentVolumeClaim, error) {
|
||||
o, exists, err := s.Get(&api.PersistentVolumeClaim{ObjectMeta: api.ObjectMeta{Namespace: namespace, Name: id}})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error retrieving PersistentVolumeClaim '%s/%s' from cache: %v", namespace, id, err)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("PersistentVolumeClaim '%s/%s' is not in cache", namespace, id)
|
||||
}
|
||||
|
||||
return o.(*api.PersistentVolumeClaim), nil
|
||||
}
|
||||
721
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers_test.go
generated
vendored
Normal file
721
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listers_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,721 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
||||
func TestStoreToNodeLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
ids := sets.NewString("foo", "bar", "baz")
|
||||
for id := range ids {
|
||||
store.Add(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}})
|
||||
}
|
||||
sml := StoreToNodeLister{store}
|
||||
|
||||
gotNodes, err := sml.List()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
got := make([]string, len(gotNodes.Items))
|
||||
for ix := range gotNodes.Items {
|
||||
got[ix] = gotNodes.Items[ix].Name
|
||||
}
|
||||
if !ids.HasAll(got...) || len(got) != len(ids) {
|
||||
t.Errorf("Expected %v, got %v", ids, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToNodeConditionLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
nodes := []*api.Node{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Status: api.NodeStatus{
|
||||
Conditions: []api.NodeCondition{
|
||||
{
|
||||
Type: api.NodeReady,
|
||||
Status: api.ConditionTrue,
|
||||
},
|
||||
{
|
||||
Type: api.NodeOutOfDisk,
|
||||
Status: api.ConditionFalse,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar"},
|
||||
Status: api.NodeStatus{
|
||||
Conditions: []api.NodeCondition{
|
||||
{
|
||||
Type: api.NodeOutOfDisk,
|
||||
Status: api.ConditionTrue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "baz"},
|
||||
Status: api.NodeStatus{
|
||||
Conditions: []api.NodeCondition{
|
||||
{
|
||||
Type: api.NodeReady,
|
||||
Status: api.ConditionFalse,
|
||||
},
|
||||
{
|
||||
Type: api.NodeOutOfDisk,
|
||||
Status: api.ConditionUnknown,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, n := range nodes {
|
||||
store.Add(n)
|
||||
}
|
||||
|
||||
predicate := func(node api.Node) bool {
|
||||
for _, cond := range node.Status.Conditions {
|
||||
if cond.Type == api.NodeOutOfDisk && cond.Status == api.ConditionTrue {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
snl := StoreToNodeLister{store}
|
||||
sncl := snl.NodeCondition(predicate)
|
||||
|
||||
want := sets.NewString("foo", "baz")
|
||||
gotNodes, err := sncl.List()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
got := make([]string, len(gotNodes.Items))
|
||||
for ix := range gotNodes.Items {
|
||||
got[ix] = gotNodes.Items[ix].Name
|
||||
}
|
||||
if !want.HasAll(got...) || len(got) != len(want) {
|
||||
t.Errorf("Expected %v, got %v", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToReplicationControllerLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
lister := StoreToReplicationControllerLister{store}
|
||||
testCases := []struct {
|
||||
inRCs []*api.ReplicationController
|
||||
list func() ([]api.ReplicationController, error)
|
||||
outRCNames sets.String
|
||||
expectErr bool
|
||||
}{
|
||||
// Basic listing with all labels and no selectors
|
||||
{
|
||||
inRCs: []*api.ReplicationController{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
},
|
||||
list: func() ([]api.ReplicationController, error) {
|
||||
return lister.List()
|
||||
},
|
||||
outRCNames: sets.NewString("basic"),
|
||||
},
|
||||
// No pod labels
|
||||
{
|
||||
inRCs: []*api.ReplicationController{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Selector: map[string]string{"foo": "baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]api.ReplicationController, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"},
|
||||
}
|
||||
return lister.GetPodControllers(pod)
|
||||
},
|
||||
outRCNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
},
|
||||
// No RC selectors
|
||||
{
|
||||
inRCs: []*api.ReplicationController{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
},
|
||||
},
|
||||
list: func() ([]api.ReplicationController, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Namespace: "ns",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
}
|
||||
return lister.GetPodControllers(pod)
|
||||
},
|
||||
outRCNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
},
|
||||
// Matching labels to selectors and namespace
|
||||
{
|
||||
inRCs: []*api.ReplicationController{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]api.ReplicationController, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
Namespace: "ns",
|
||||
},
|
||||
}
|
||||
return lister.GetPodControllers(pod)
|
||||
},
|
||||
outRCNames: sets.NewString("bar"),
|
||||
},
|
||||
}
|
||||
for _, c := range testCases {
|
||||
for _, r := range c.inRCs {
|
||||
store.Add(r)
|
||||
}
|
||||
|
||||
gotControllers, err := c.list()
|
||||
if err != nil && c.expectErr {
|
||||
continue
|
||||
} else if c.expectErr {
|
||||
t.Error("Expected error, got none")
|
||||
continue
|
||||
} else if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
continue
|
||||
}
|
||||
gotNames := make([]string, len(gotControllers))
|
||||
for ix := range gotControllers {
|
||||
gotNames[ix] = gotControllers[ix].Name
|
||||
}
|
||||
if !c.outRCNames.HasAll(gotNames...) || len(gotNames) != len(c.outRCNames) {
|
||||
t.Errorf("Unexpected got controllers %+v expected %+v", gotNames, c.outRCNames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToReplicaSetLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
lister := StoreToReplicaSetLister{store}
|
||||
testCases := []struct {
|
||||
inRSs []*extensions.ReplicaSet
|
||||
list func() ([]extensions.ReplicaSet, error)
|
||||
outRSNames sets.String
|
||||
expectErr bool
|
||||
}{
|
||||
// Basic listing with all labels and no selectors
|
||||
{
|
||||
inRSs: []*extensions.ReplicaSet{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
},
|
||||
list: func() ([]extensions.ReplicaSet, error) {
|
||||
return lister.List()
|
||||
},
|
||||
outRSNames: sets.NewString("basic"),
|
||||
},
|
||||
// No pod labels
|
||||
{
|
||||
inRSs: []*extensions.ReplicaSet{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
Spec: extensions.ReplicaSetSpec{
|
||||
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.ReplicaSet, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"},
|
||||
}
|
||||
return lister.GetPodReplicaSets(pod)
|
||||
},
|
||||
outRSNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
},
|
||||
// No ReplicaSet selectors
|
||||
{
|
||||
inRSs: []*extensions.ReplicaSet{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.ReplicaSet, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Namespace: "ns",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
}
|
||||
return lister.GetPodReplicaSets(pod)
|
||||
},
|
||||
outRSNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
},
|
||||
// Matching labels to selectors and namespace
|
||||
{
|
||||
inRSs: []*extensions.ReplicaSet{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: extensions.ReplicaSetSpec{
|
||||
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
|
||||
Spec: extensions.ReplicaSetSpec{
|
||||
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.ReplicaSet, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
Namespace: "ns",
|
||||
},
|
||||
}
|
||||
return lister.GetPodReplicaSets(pod)
|
||||
},
|
||||
outRSNames: sets.NewString("bar"),
|
||||
},
|
||||
}
|
||||
for _, c := range testCases {
|
||||
for _, r := range c.inRSs {
|
||||
store.Add(r)
|
||||
}
|
||||
|
||||
gotRSs, err := c.list()
|
||||
if err != nil && c.expectErr {
|
||||
continue
|
||||
} else if c.expectErr {
|
||||
t.Error("Expected error, got none")
|
||||
continue
|
||||
} else if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
continue
|
||||
}
|
||||
gotNames := make([]string, len(gotRSs))
|
||||
for ix := range gotRSs {
|
||||
gotNames[ix] = gotRSs[ix].Name
|
||||
}
|
||||
if !c.outRSNames.HasAll(gotNames...) || len(gotNames) != len(c.outRSNames) {
|
||||
t.Errorf("Unexpected got ReplicaSets %+v expected %+v", gotNames, c.outRSNames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToDaemonSetLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
lister := StoreToDaemonSetLister{store}
|
||||
testCases := []struct {
|
||||
inDSs []*extensions.DaemonSet
|
||||
list func() ([]extensions.DaemonSet, error)
|
||||
outDaemonSetNames sets.String
|
||||
expectErr bool
|
||||
}{
|
||||
// Basic listing
|
||||
{
|
||||
inDSs: []*extensions.DaemonSet{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
},
|
||||
list: func() ([]extensions.DaemonSet, error) {
|
||||
list, err := lister.List()
|
||||
return list.Items, err
|
||||
},
|
||||
outDaemonSetNames: sets.NewString("basic"),
|
||||
},
|
||||
// Listing multiple daemon sets
|
||||
{
|
||||
inDSs: []*extensions.DaemonSet{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex2"}},
|
||||
},
|
||||
list: func() ([]extensions.DaemonSet, error) {
|
||||
list, err := lister.List()
|
||||
return list.Items, err
|
||||
},
|
||||
outDaemonSetNames: sets.NewString("basic", "complex", "complex2"),
|
||||
},
|
||||
// No pod labels
|
||||
{
|
||||
inDSs: []*extensions.DaemonSet{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.DaemonSet, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"},
|
||||
}
|
||||
return lister.GetPodDaemonSets(pod)
|
||||
},
|
||||
outDaemonSetNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
},
|
||||
// No DS selectors
|
||||
{
|
||||
inDSs: []*extensions.DaemonSet{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.DaemonSet, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Namespace: "ns",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
}
|
||||
return lister.GetPodDaemonSets(pod)
|
||||
},
|
||||
outDaemonSetNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
},
|
||||
// Matching labels to selectors and namespace
|
||||
{
|
||||
inDSs: []*extensions.DaemonSet{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.DaemonSet, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
Namespace: "ns",
|
||||
},
|
||||
}
|
||||
return lister.GetPodDaemonSets(pod)
|
||||
},
|
||||
outDaemonSetNames: sets.NewString("bar"),
|
||||
},
|
||||
}
|
||||
for _, c := range testCases {
|
||||
for _, r := range c.inDSs {
|
||||
store.Add(r)
|
||||
}
|
||||
|
||||
daemonSets, err := c.list()
|
||||
if err != nil && c.expectErr {
|
||||
continue
|
||||
} else if c.expectErr {
|
||||
t.Error("Expected error, got none")
|
||||
continue
|
||||
} else if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
continue
|
||||
}
|
||||
daemonSetNames := make([]string, len(daemonSets))
|
||||
for ix := range daemonSets {
|
||||
daemonSetNames[ix] = daemonSets[ix].Name
|
||||
}
|
||||
if !c.outDaemonSetNames.HasAll(daemonSetNames...) || len(daemonSetNames) != len(c.outDaemonSetNames) {
|
||||
t.Errorf("Unexpected got controllers %+v expected %+v", daemonSetNames, c.outDaemonSetNames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToJobLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
lister := StoreToJobLister{store}
|
||||
testCases := []struct {
|
||||
inJobs []*extensions.Job
|
||||
list func() ([]extensions.Job, error)
|
||||
outJobNames sets.String
|
||||
expectErr bool
|
||||
msg string
|
||||
}{
|
||||
// Basic listing
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list, err := lister.List()
|
||||
return list.Items, err
|
||||
},
|
||||
outJobNames: sets.NewString("basic"),
|
||||
msg: "basic listing failed",
|
||||
},
|
||||
// Listing multiple jobs
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "basic"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex"}},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "complex2"}},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
list, err := lister.List()
|
||||
return list.Items, err
|
||||
},
|
||||
outJobNames: sets.NewString("basic", "complex", "complex2"),
|
||||
msg: "listing multiple jobs failed",
|
||||
},
|
||||
// No pod labels
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "baz"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "pod", Namespace: "ns"},
|
||||
}
|
||||
return lister.GetPodJobs(pod)
|
||||
},
|
||||
outJobNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
msg: "listing jobs failed when pod has no labels: expected error, got none",
|
||||
},
|
||||
// No Job selectors
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod",
|
||||
Namespace: "ns",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
}
|
||||
return lister.GetPodJobs(pod)
|
||||
},
|
||||
outJobNames: sets.NewString(),
|
||||
expectErr: true,
|
||||
msg: "listing jobs failed when job has no selector: expected error, got none",
|
||||
},
|
||||
// Matching labels to selectors and namespace
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
Namespace: "ns",
|
||||
},
|
||||
}
|
||||
return lister.GetPodJobs(pod)
|
||||
},
|
||||
outJobNames: sets.NewString("bar"),
|
||||
msg: "listing jobs with namespace and selector failed",
|
||||
},
|
||||
// Matching labels to selectors and namespace, error case
|
||||
{
|
||||
inJobs: []*extensions.Job{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "foo"},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "bar"},
|
||||
Spec: extensions.JobSpec{
|
||||
Selector: &unversioned.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
list: func() ([]extensions.Job, error) {
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "pod",
|
||||
Labels: map[string]string{"foo": "bar"},
|
||||
Namespace: "baz",
|
||||
},
|
||||
}
|
||||
return lister.GetPodJobs(pod)
|
||||
},
|
||||
expectErr: true,
|
||||
msg: "listing jobs with namespace and selector failed: expected error, got none",
|
||||
},
|
||||
}
|
||||
for _, c := range testCases {
|
||||
for _, r := range c.inJobs {
|
||||
store.Add(r)
|
||||
}
|
||||
|
||||
Jobs, err := c.list()
|
||||
if err != nil && c.expectErr {
|
||||
continue
|
||||
} else if c.expectErr {
|
||||
t.Errorf("%v", c.msg)
|
||||
continue
|
||||
} else if err != nil {
|
||||
t.Errorf("Unexpected error %#v", err)
|
||||
continue
|
||||
}
|
||||
JobNames := make([]string, len(Jobs))
|
||||
for ix := range Jobs {
|
||||
JobNames[ix] = Jobs[ix].Name
|
||||
}
|
||||
if !c.outJobNames.HasAll(JobNames...) || len(JobNames) != len(c.outJobNames) {
|
||||
t.Errorf("%v : expected %v, got %v", c.msg, JobNames, c.outJobNames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToPodLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
ids := []string{"foo", "bar", "baz"}
|
||||
for _, id := range ids {
|
||||
store.Add(&api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: id,
|
||||
Labels: map[string]string{"name": id},
|
||||
},
|
||||
})
|
||||
}
|
||||
spl := StoreToPodLister{store}
|
||||
|
||||
for _, id := range ids {
|
||||
got, err := spl.List(labels.Set{"name": id}.AsSelector())
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
continue
|
||||
}
|
||||
if e, a := 1, len(got); e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
continue
|
||||
}
|
||||
if e, a := id, got[0].Name; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
continue
|
||||
}
|
||||
|
||||
exists, err := spl.Exists(&api.Pod{ObjectMeta: api.ObjectMeta{Name: id}})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !exists {
|
||||
t.Errorf("exists returned false for %v", id)
|
||||
}
|
||||
}
|
||||
|
||||
exists, err := spl.Exists(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "qux"}})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if exists {
|
||||
t.Error("Unexpected pod exists")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToServiceLister(t *testing.T) {
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
store.Add(&api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{},
|
||||
},
|
||||
})
|
||||
store.Add(&api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}})
|
||||
ssl := StoreToServiceLister{store}
|
||||
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foopod",
|
||||
Labels: map[string]string{"role": "foo"},
|
||||
},
|
||||
}
|
||||
|
||||
services, err := ssl.GetPodServices(pod)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(services) != 1 {
|
||||
t.Fatalf("Expected 1 service, got %v", len(services))
|
||||
}
|
||||
if e, a := "foo", services[0].Name; e != a {
|
||||
t.Errorf("Expected service %q, got %q", e, a)
|
||||
}
|
||||
}
|
||||
86
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch.go
generated
vendored
Normal file
86
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch.go
generated
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ListFunc knows how to list resources
|
||||
type ListFunc func(options api.ListOptions) (runtime.Object, error)
|
||||
|
||||
// WatchFunc knows how to watch resources
|
||||
type WatchFunc func(options api.ListOptions) (watch.Interface, error)
|
||||
|
||||
// ListWatch knows how to list and watch a set of apiserver resources. It satisfies the ListerWatcher interface.
|
||||
// It is a convenience function for users of NewReflector, etc.
|
||||
// ListFunc and WatchFunc must not be nil
|
||||
type ListWatch struct {
|
||||
ListFunc ListFunc
|
||||
WatchFunc WatchFunc
|
||||
}
|
||||
|
||||
// Getter interface knows how to access Get method from RESTClient.
|
||||
type Getter interface {
|
||||
Get() *client.Request
|
||||
}
|
||||
|
||||
// NewListWatchFromClient creates a new ListWatch from the specified client, resource, namespace and field selector.
|
||||
func NewListWatchFromClient(c Getter, resource string, namespace string, fieldSelector fields.Selector) *ListWatch {
|
||||
listFunc := func(options api.ListOptions) (runtime.Object, error) {
|
||||
return c.Get().
|
||||
Namespace(namespace).
|
||||
Resource(resource).
|
||||
VersionedParams(&options, api.ParameterCodec).
|
||||
FieldsSelectorParam(fieldSelector).
|
||||
Do().
|
||||
Get()
|
||||
}
|
||||
watchFunc := func(options api.ListOptions) (watch.Interface, error) {
|
||||
return c.Get().
|
||||
Prefix("watch").
|
||||
Namespace(namespace).
|
||||
Resource(resource).
|
||||
VersionedParams(&options, api.ParameterCodec).
|
||||
FieldsSelectorParam(fieldSelector).
|
||||
Watch()
|
||||
}
|
||||
return &ListWatch{ListFunc: listFunc, WatchFunc: watchFunc}
|
||||
}
|
||||
|
||||
func timeoutFromListOptions(options api.ListOptions) time.Duration {
|
||||
if options.TimeoutSeconds != nil {
|
||||
return time.Duration(*options.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// List a set of apiserver resources
|
||||
func (lw *ListWatch) List(options api.ListOptions) (runtime.Object, error) {
|
||||
return lw.ListFunc(options)
|
||||
}
|
||||
|
||||
// Watch a set of apiserver resources
|
||||
func (lw *ListWatch) Watch(options api.ListOptions) (watch.Interface, error) {
|
||||
return lw.WatchFunc(options)
|
||||
}
|
||||
173
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch_test.go
generated
vendored
Normal file
173
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/listwatch_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
utiltesting "k8s.io/kubernetes/pkg/util/testing"
|
||||
)
|
||||
|
||||
func parseSelectorOrDie(s string) fields.Selector {
|
||||
selector, err := fields.ParseSelector(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// buildQueryValues is a convenience function for knowing if a namespace should be in a query param or not
|
||||
func buildQueryValues(query url.Values) url.Values {
|
||||
v := url.Values{}
|
||||
if query != nil {
|
||||
for key, values := range query {
|
||||
for _, value := range values {
|
||||
v.Add(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func buildLocation(resourcePath string, query url.Values) string {
|
||||
return resourcePath + "?" + query.Encode()
|
||||
}
|
||||
|
||||
func TestListWatchesCanList(t *testing.T) {
|
||||
fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(testapi.Default.GroupVersion().String())
|
||||
table := []struct {
|
||||
location string
|
||||
resource string
|
||||
namespace string
|
||||
fieldSelector fields.Selector
|
||||
}{
|
||||
// Node
|
||||
{
|
||||
location: testapi.Default.ResourcePath("nodes", api.NamespaceAll, ""),
|
||||
resource: "nodes",
|
||||
namespace: api.NamespaceAll,
|
||||
fieldSelector: parseSelectorOrDie(""),
|
||||
},
|
||||
// pod with "assigned" field selector.
|
||||
{
|
||||
location: buildLocation(
|
||||
testapi.Default.ResourcePath("pods", api.NamespaceAll, ""),
|
||||
buildQueryValues(url.Values{fieldSelectorQueryParamName: []string{"spec.host="}})),
|
||||
resource: "pods",
|
||||
namespace: api.NamespaceAll,
|
||||
fieldSelector: fields.Set{"spec.host": ""}.AsSelector(),
|
||||
},
|
||||
// pod in namespace "foo"
|
||||
{
|
||||
location: buildLocation(
|
||||
testapi.Default.ResourcePath("pods", "foo", ""),
|
||||
buildQueryValues(url.Values{fieldSelectorQueryParamName: []string{"spec.host="}})),
|
||||
resource: "pods",
|
||||
namespace: "foo",
|
||||
fieldSelector: fields.Set{"spec.host": ""}.AsSelector(),
|
||||
},
|
||||
}
|
||||
for _, item := range table {
|
||||
handler := utiltesting.FakeHandler{
|
||||
StatusCode: 500,
|
||||
ResponseBody: "",
|
||||
T: t,
|
||||
}
|
||||
server := httptest.NewServer(&handler)
|
||||
// TODO: Uncomment when fix #19254
|
||||
// defer server.Close()
|
||||
client := client.NewOrDie(&client.Config{Host: server.URL, ContentConfig: client.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
|
||||
lw := NewListWatchFromClient(client, item.resource, item.namespace, item.fieldSelector)
|
||||
// This test merely tests that the correct request is made.
|
||||
lw.List(api.ListOptions{})
|
||||
handler.ValidateRequest(t, item.location, "GET", nil)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListWatchesCanWatch(t *testing.T) {
|
||||
fieldSelectorQueryParamName := unversioned.FieldSelectorQueryParam(testapi.Default.GroupVersion().String())
|
||||
table := []struct {
|
||||
rv string
|
||||
location string
|
||||
resource string
|
||||
namespace string
|
||||
fieldSelector fields.Selector
|
||||
}{
|
||||
// Node
|
||||
{
|
||||
location: buildLocation(
|
||||
testapi.Default.ResourcePathWithPrefix("watch", "nodes", api.NamespaceAll, ""),
|
||||
buildQueryValues(url.Values{})),
|
||||
rv: "",
|
||||
resource: "nodes",
|
||||
namespace: api.NamespaceAll,
|
||||
fieldSelector: parseSelectorOrDie(""),
|
||||
},
|
||||
{
|
||||
location: buildLocation(
|
||||
testapi.Default.ResourcePathWithPrefix("watch", "nodes", api.NamespaceAll, ""),
|
||||
buildQueryValues(url.Values{"resourceVersion": []string{"42"}})),
|
||||
rv: "42",
|
||||
resource: "nodes",
|
||||
namespace: api.NamespaceAll,
|
||||
fieldSelector: parseSelectorOrDie(""),
|
||||
},
|
||||
// pod with "assigned" field selector.
|
||||
{
|
||||
location: buildLocation(
|
||||
testapi.Default.ResourcePathWithPrefix("watch", "pods", api.NamespaceAll, ""),
|
||||
buildQueryValues(url.Values{fieldSelectorQueryParamName: []string{"spec.host="}, "resourceVersion": []string{"0"}})),
|
||||
rv: "0",
|
||||
resource: "pods",
|
||||
namespace: api.NamespaceAll,
|
||||
fieldSelector: fields.Set{"spec.host": ""}.AsSelector(),
|
||||
},
|
||||
// pod with namespace foo and assigned field selector
|
||||
{
|
||||
location: buildLocation(
|
||||
testapi.Default.ResourcePathWithPrefix("watch", "pods", "foo", ""),
|
||||
buildQueryValues(url.Values{fieldSelectorQueryParamName: []string{"spec.host="}, "resourceVersion": []string{"0"}})),
|
||||
rv: "0",
|
||||
resource: "pods",
|
||||
namespace: "foo",
|
||||
fieldSelector: fields.Set{"spec.host": ""}.AsSelector(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
handler := utiltesting.FakeHandler{
|
||||
StatusCode: 500,
|
||||
ResponseBody: "",
|
||||
T: t,
|
||||
}
|
||||
server := httptest.NewServer(&handler)
|
||||
// TODO: Uncomment when fix #19254
|
||||
// defer server.Close()
|
||||
client := client.NewOrDie(&client.Config{Host: server.URL, ContentConfig: client.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
|
||||
lw := NewListWatchFromClient(client, item.resource, item.namespace, item.fieldSelector)
|
||||
// This test merely tests that the correct request is made.
|
||||
lw.Watch(api.ListOptions{ResourceVersion: item.rv})
|
||||
handler.ValidateRequest(t, item.location, "GET", nil)
|
||||
}
|
||||
}
|
||||
382
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector.go
generated
vendored
Normal file
382
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector.go
generated
vendored
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/url"
|
||||
"reflect"
|
||||
goruntime "runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apierrs "k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ListerWatcher is any object that knows how to perform an initial list and start a watch on a resource.
|
||||
type ListerWatcher interface {
|
||||
// List should return a list type object; the Items field will be extracted, and the
|
||||
// ResourceVersion field will be used to start the watch in the right place.
|
||||
List(options api.ListOptions) (runtime.Object, error)
|
||||
// Watch should begin a watch at the specified version.
|
||||
Watch(options api.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
// Reflector watches a specified resource and causes all changes to be reflected in the given store.
|
||||
type Reflector struct {
|
||||
// name identifies this reflector. By default it will be a file:line if possible.
|
||||
name string
|
||||
|
||||
// The type of object we expect to place in the store.
|
||||
expectedType reflect.Type
|
||||
// The destination to sync up with the watch source
|
||||
store Store
|
||||
// listerWatcher is used to perform lists and watches.
|
||||
listerWatcher ListerWatcher
|
||||
// period controls timing between one watch ending and
|
||||
// the beginning of the next one.
|
||||
period time.Duration
|
||||
resyncPeriod time.Duration
|
||||
// now() returns current time - exposed for testing purposes
|
||||
now func() time.Time
|
||||
// nextResync is approximate time of next resync (0 if not scheduled)
|
||||
nextResync time.Time
|
||||
// lastSyncResourceVersion is the resource version token last
|
||||
// observed when doing a sync with the underlying store
|
||||
// it is thread safe, but not synchronized with the underlying store
|
||||
lastSyncResourceVersion string
|
||||
// lastSyncResourceVersionMutex guards read/write access to lastSyncResourceVersion
|
||||
lastSyncResourceVersionMutex sync.RWMutex
|
||||
}
|
||||
|
||||
var (
|
||||
// We try to spread the load on apiserver by setting timeouts for
|
||||
// watch requests - it is random in [minWatchTimeout, 2*minWatchTimeout].
|
||||
// However, it can be modified to avoid periodic resync to break the
|
||||
// TCP connection.
|
||||
minWatchTimeout = 5 * time.Minute
|
||||
// If we are within 'forceResyncThreshold' from the next planned resync
|
||||
// and are just before issuing Watch(), resync will be forced now.
|
||||
forceResyncThreshold = 3 * time.Second
|
||||
// We try to set timeouts for Watch() so that we will finish about
|
||||
// than 'timeoutThreshold' from next planned periodic resync.
|
||||
timeoutThreshold = 1 * time.Second
|
||||
)
|
||||
|
||||
// NewNamespaceKeyedIndexerAndReflector creates an Indexer and a Reflector
|
||||
// The indexer is configured to key on namespace
|
||||
func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interface{}, resyncPeriod time.Duration) (indexer Indexer, reflector *Reflector) {
|
||||
indexer = NewIndexer(MetaNamespaceKeyFunc, Indexers{"namespace": MetaNamespaceIndexFunc})
|
||||
reflector = NewReflector(lw, expectedType, indexer, resyncPeriod)
|
||||
return indexer, reflector
|
||||
}
|
||||
|
||||
// NewReflector creates a new Reflector object which will keep the given store up to
|
||||
// date with the server's contents for the given resource. Reflector promises to
|
||||
// only put things in the store that have the type of expectedType, unless expectedType
|
||||
// is nil. If resyncPeriod is non-zero, then lists will be executed after every
|
||||
// resyncPeriod, so that you can use reflectors to periodically process everything as
|
||||
// well as incrementally processing the things that change.
|
||||
func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector {
|
||||
return NewNamedReflector(getDefaultReflectorName(internalPackages...), lw, expectedType, store, resyncPeriod)
|
||||
}
|
||||
|
||||
// NewNamedReflector same as NewReflector, but with a specified name for logging
|
||||
func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector {
|
||||
r := &Reflector{
|
||||
name: name,
|
||||
listerWatcher: lw,
|
||||
store: store,
|
||||
expectedType: reflect.TypeOf(expectedType),
|
||||
period: time.Second,
|
||||
resyncPeriod: resyncPeriod,
|
||||
now: time.Now,
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// internalPackages are packages that ignored when creating a default reflector name. These packages are in the common
|
||||
// call chains to NewReflector, so they'd be low entropy names for reflectors
|
||||
var internalPackages = []string{"kubernetes/pkg/client/cache/", "kubernetes/pkg/controller/framework/"}
|
||||
|
||||
// getDefaultReflectorName walks back through the call stack until we find a caller from outside of the ignoredPackages
|
||||
// it returns back a shortpath/filename:line to aid in identification of this reflector when it starts logging
|
||||
func getDefaultReflectorName(ignoredPackages ...string) string {
|
||||
name := "????"
|
||||
outer:
|
||||
for i := 1; i < 10; i++ {
|
||||
_, file, line, ok := goruntime.Caller(i)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
for _, ignoredPackage := range ignoredPackages {
|
||||
if strings.Contains(file, ignoredPackage) {
|
||||
continue outer
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pkgLocation := strings.LastIndex(file, "/pkg/")
|
||||
if pkgLocation >= 0 {
|
||||
file = file[pkgLocation+1:]
|
||||
}
|
||||
name = fmt.Sprintf("%s:%d", file, line)
|
||||
break
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// Run starts a watch and handles watch events. Will restart the watch if it is closed.
|
||||
// Run starts a goroutine and returns immediately.
|
||||
func (r *Reflector) Run() {
|
||||
go wait.Until(func() { r.ListAndWatch(wait.NeverStop) }, r.period, wait.NeverStop)
|
||||
}
|
||||
|
||||
// RunUntil starts a watch and handles watch events. Will restart the watch if it is closed.
|
||||
// RunUntil starts a goroutine and returns immediately. It will exit when stopCh is closed.
|
||||
func (r *Reflector) RunUntil(stopCh <-chan struct{}) {
|
||||
go wait.Until(func() { r.ListAndWatch(stopCh) }, r.period, stopCh)
|
||||
}
|
||||
|
||||
var (
|
||||
// nothing will ever be sent down this channel
|
||||
neverExitWatch <-chan time.Time = make(chan time.Time)
|
||||
|
||||
// Used to indicate that watching stopped so that a resync could happen.
|
||||
errorResyncRequested = errors.New("resync channel fired")
|
||||
|
||||
// Used to indicate that watching stopped because of a signal from the stop
|
||||
// channel passed in from a client of the reflector.
|
||||
errorStopRequested = errors.New("Stop requested")
|
||||
)
|
||||
|
||||
// resyncChan returns a channel which will receive something when a resync is
|
||||
// required, and a cleanup function.
|
||||
func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) {
|
||||
if r.resyncPeriod == 0 {
|
||||
r.nextResync = time.Time{}
|
||||
return neverExitWatch, func() bool { return false }
|
||||
}
|
||||
// The cleanup function is required: imagine the scenario where watches
|
||||
// always fail so we end up listing frequently. Then, if we don't
|
||||
// manually stop the timer, we could end up with many timers active
|
||||
// concurrently.
|
||||
r.nextResync = r.now().Add(r.resyncPeriod)
|
||||
t := time.NewTimer(r.resyncPeriod)
|
||||
return t.C, t.Stop
|
||||
}
|
||||
|
||||
// We want to avoid situations when periodic resyncing is breaking the TCP
|
||||
// connection.
|
||||
// If response`s body is not read to completion before calling body.Close(),
|
||||
// that TCP connection will not be reused in the future - see #15664 issue
|
||||
// for more details.
|
||||
// Thus, we set timeout for watch requests to be smaller than the remaining
|
||||
// time until next periodic resync and force resyncing ourself to avoid
|
||||
// breaking TCP connection.
|
||||
//
|
||||
// TODO: This should be parametrizable based on server load.
|
||||
func (r *Reflector) timeoutForWatch() *int64 {
|
||||
randTimeout := time.Duration(float64(minWatchTimeout) * (rand.Float64() + 1.0))
|
||||
timeout := r.nextResync.Sub(r.now()) - timeoutThreshold
|
||||
if timeout < 0 || randTimeout < timeout {
|
||||
timeout = randTimeout
|
||||
}
|
||||
timeoutSeconds := int64(timeout.Seconds())
|
||||
return &timeoutSeconds
|
||||
}
|
||||
|
||||
// Returns true if we are close enough to next planned periodic resync
|
||||
// and we can force resyncing ourself now.
|
||||
func (r *Reflector) canForceResyncNow() bool {
|
||||
if r.nextResync.IsZero() {
|
||||
return false
|
||||
}
|
||||
return r.now().Add(forceResyncThreshold).After(r.nextResync)
|
||||
}
|
||||
|
||||
// ListAndWatch first lists all items and get the resource version at the moment of call,
|
||||
// and then use the resource version to watch.
|
||||
// It returns error if ListAndWatch didn't even try to initialize watch.
|
||||
func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
|
||||
var resourceVersion string
|
||||
resyncCh, cleanup := r.resyncChan()
|
||||
defer cleanup()
|
||||
|
||||
// Explicitly set "0" as resource version - it's fine for the List()
|
||||
// to be served from cache and potentially be delayed relative to
|
||||
// etcd contents. Reflector framework will catch up via Watch() eventually.
|
||||
options := api.ListOptions{ResourceVersion: "0"}
|
||||
list, err := r.listerWatcher.List(options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedType, err)
|
||||
}
|
||||
metaInterface, err := meta.Accessor(list)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: Unable to understand list result %#v", r.name, list)
|
||||
}
|
||||
resourceVersion = metaInterface.GetResourceVersion()
|
||||
items, err := meta.ExtractList(list)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: Unable to understand list result %#v (%v)", r.name, list, err)
|
||||
}
|
||||
if err := r.syncWith(items, resourceVersion); err != nil {
|
||||
return fmt.Errorf("%s: Unable to sync list result: %v", r.name, err)
|
||||
}
|
||||
r.setLastSyncResourceVersion(resourceVersion)
|
||||
|
||||
for {
|
||||
options := api.ListOptions{
|
||||
ResourceVersion: resourceVersion,
|
||||
// We want to avoid situations when resyncing is breaking the TCP connection
|
||||
// - see comment for 'timeoutForWatch()' for more details.
|
||||
TimeoutSeconds: r.timeoutForWatch(),
|
||||
}
|
||||
w, err := r.listerWatcher.Watch(options)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case io.EOF:
|
||||
// watch closed normally
|
||||
case io.ErrUnexpectedEOF:
|
||||
glog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.expectedType, err)
|
||||
default:
|
||||
utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.expectedType, err))
|
||||
}
|
||||
// If this is "connection refused" error, it means that most likely apiserver is not responsive.
|
||||
// It doesn't make sense to re-list all objects because most likely we will be able to restart
|
||||
// watch where we ended.
|
||||
// If that's the case wait and resend watch request.
|
||||
if urlError, ok := err.(*url.Error); ok {
|
||||
if opError, ok := urlError.Err.(*net.OpError); ok {
|
||||
if errno, ok := opError.Err.(syscall.Errno); ok && errno == syscall.ECONNREFUSED {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := r.watchHandler(w, &resourceVersion, resyncCh, stopCh); err != nil {
|
||||
if err != errorResyncRequested && err != errorStopRequested {
|
||||
glog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedType, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if r.canForceResyncNow() {
|
||||
glog.V(4).Infof("%s: next resync planned for %#v, forcing now", r.name, r.nextResync)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// syncWith replaces the store's items with the given list.
|
||||
func (r *Reflector) syncWith(items []runtime.Object, resourceVersion string) error {
|
||||
found := make([]interface{}, 0, len(items))
|
||||
for _, item := range items {
|
||||
found = append(found, item)
|
||||
}
|
||||
return r.store.Replace(found, resourceVersion)
|
||||
}
|
||||
|
||||
// watchHandler watches w and keeps *resourceVersion up to date.
|
||||
func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string, resyncCh <-chan time.Time, stopCh <-chan struct{}) error {
|
||||
start := time.Now()
|
||||
eventCount := 0
|
||||
|
||||
// Stopping the watcher should be idempotent and if we return from this function there's no way
|
||||
// we're coming back in with the same watch interface.
|
||||
defer w.Stop()
|
||||
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case <-stopCh:
|
||||
return errorStopRequested
|
||||
case <-resyncCh:
|
||||
return errorResyncRequested
|
||||
case event, ok := <-w.ResultChan():
|
||||
if !ok {
|
||||
break loop
|
||||
}
|
||||
if event.Type == watch.Error {
|
||||
return apierrs.FromObject(event.Object)
|
||||
}
|
||||
if e, a := r.expectedType, reflect.TypeOf(event.Object); e != nil && e != a {
|
||||
utilruntime.HandleError(fmt.Errorf("%s: expected type %v, but watch event object had type %v", r.name, e, a))
|
||||
continue
|
||||
}
|
||||
meta, err := meta.Accessor(event.Object)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event))
|
||||
continue
|
||||
}
|
||||
newResourceVersion := meta.GetResourceVersion()
|
||||
switch event.Type {
|
||||
case watch.Added:
|
||||
r.store.Add(event.Object)
|
||||
case watch.Modified:
|
||||
r.store.Update(event.Object)
|
||||
case watch.Deleted:
|
||||
// TODO: Will any consumers need access to the "last known
|
||||
// state", which is passed in event.Object? If so, may need
|
||||
// to change this.
|
||||
r.store.Delete(event.Object)
|
||||
default:
|
||||
utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event))
|
||||
}
|
||||
*resourceVersion = newResourceVersion
|
||||
r.setLastSyncResourceVersion(newResourceVersion)
|
||||
eventCount++
|
||||
}
|
||||
}
|
||||
|
||||
watchDuration := time.Now().Sub(start)
|
||||
if watchDuration < 1*time.Second && eventCount == 0 {
|
||||
glog.V(4).Infof("%s: Unexpected watch close - watch lasted less than a second and no items received", r.name)
|
||||
return errors.New("very short watch")
|
||||
}
|
||||
glog.V(4).Infof("%s: Watch close - %v total %v items received", r.name, r.expectedType, eventCount)
|
||||
return nil
|
||||
}
|
||||
|
||||
// LastSyncResourceVersion is the resource version observed when last sync with the underlying store
|
||||
// The value returned is not synchronized with access to the underlying store and is not thread-safe
|
||||
func (r *Reflector) LastSyncResourceVersion() string {
|
||||
r.lastSyncResourceVersionMutex.RLock()
|
||||
defer r.lastSyncResourceVersionMutex.RUnlock()
|
||||
return r.lastSyncResourceVersion
|
||||
}
|
||||
|
||||
func (r *Reflector) setLastSyncResourceVersion(v string) {
|
||||
r.lastSyncResourceVersionMutex.Lock()
|
||||
defer r.lastSyncResourceVersionMutex.Unlock()
|
||||
r.lastSyncResourceVersion = v
|
||||
}
|
||||
404
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector_test.go
generated
vendored
Normal file
404
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/reflector_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
type testLW struct {
|
||||
ListFunc func() (runtime.Object, error)
|
||||
WatchFunc func(resourceVersion string) (watch.Interface, error)
|
||||
}
|
||||
|
||||
func (t *testLW) List(options api.ListOptions) (runtime.Object, error) {
|
||||
return t.ListFunc()
|
||||
}
|
||||
func (t *testLW) Watch(options api.ListOptions) (watch.Interface, error) {
|
||||
return t.WatchFunc(options.ResourceVersion)
|
||||
}
|
||||
|
||||
func TestCloseWatchChannelOnError(t *testing.T) {
|
||||
r := NewReflector(&testLW{}, &api.Pod{}, NewStore(MetaNamespaceKeyFunc), 0)
|
||||
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}}
|
||||
fw := watch.NewFake()
|
||||
r.listerWatcher = &testLW{
|
||||
WatchFunc: func(rv string) (watch.Interface, error) {
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func() (runtime.Object, error) {
|
||||
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
|
||||
},
|
||||
}
|
||||
go r.ListAndWatch(wait.NeverStop)
|
||||
fw.Error(pod)
|
||||
select {
|
||||
case _, ok := <-fw.ResultChan():
|
||||
if ok {
|
||||
t.Errorf("Watch channel left open after cancellation")
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Errorf("the cancellation is at least %s late", wait.ForeverTestTimeout.String())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunUntil(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
r := NewReflector(&testLW{}, &api.Pod{}, store, 0)
|
||||
fw := watch.NewFake()
|
||||
r.listerWatcher = &testLW{
|
||||
WatchFunc: func(rv string) (watch.Interface, error) {
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func() (runtime.Object, error) {
|
||||
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
|
||||
},
|
||||
}
|
||||
r.RunUntil(stopCh)
|
||||
// Synchronously add a dummy pod into the watch channel so we
|
||||
// know the RunUntil go routine is in the watch handler.
|
||||
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}})
|
||||
stopCh <- struct{}{}
|
||||
select {
|
||||
case _, ok := <-fw.ResultChan():
|
||||
if ok {
|
||||
t.Errorf("Watch channel left open after stopping the watch")
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Errorf("the cancellation is at least %s late", wait.ForeverTestTimeout.String())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorResyncChan(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, time.Millisecond)
|
||||
a, _ := g.resyncChan()
|
||||
b := time.After(wait.ForeverTestTimeout)
|
||||
select {
|
||||
case <-a:
|
||||
t.Logf("got timeout as expected")
|
||||
case <-b:
|
||||
t.Errorf("resyncChan() is at least 99 milliseconds late??")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReflectorResyncChanMany(b *testing.B) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, 25*time.Millisecond)
|
||||
// The improvement to this (calling the timer's Stop() method) makes
|
||||
// this benchmark about 40% faster.
|
||||
for i := 0; i < b.N; i++ {
|
||||
g.resyncPeriod = time.Duration(rand.Float64() * float64(time.Millisecond) * 25)
|
||||
_, stop := g.resyncChan()
|
||||
stop()
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorWatchHandlerError(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
|
||||
fw := watch.NewFake()
|
||||
go func() {
|
||||
fw.Stop()
|
||||
}()
|
||||
var resumeRV string
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch, wait.NeverStop)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorWatchHandler(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
|
||||
fw := watch.NewFake()
|
||||
s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}})
|
||||
s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}})
|
||||
go func() {
|
||||
fw.Add(&api.Service{ObjectMeta: api.ObjectMeta{Name: "rejected"}})
|
||||
fw.Delete(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}})
|
||||
fw.Modify(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "55"}})
|
||||
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "32"}})
|
||||
fw.Stop()
|
||||
}()
|
||||
var resumeRV string
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch, wait.NeverStop)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
mkPod := func(id string, rv string) *api.Pod {
|
||||
return &api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: rv}}
|
||||
}
|
||||
|
||||
table := []struct {
|
||||
Pod *api.Pod
|
||||
exists bool
|
||||
}{
|
||||
{mkPod("foo", ""), false},
|
||||
{mkPod("rejected", ""), false},
|
||||
{mkPod("bar", "55"), true},
|
||||
{mkPod("baz", "32"), true},
|
||||
}
|
||||
for _, item := range table {
|
||||
obj, exists, _ := s.Get(item.Pod)
|
||||
if e, a := item.exists, exists; e != a {
|
||||
t.Errorf("%v: expected %v, got %v", item.Pod, e, a)
|
||||
}
|
||||
if !exists {
|
||||
continue
|
||||
}
|
||||
if e, a := item.Pod.ResourceVersion, obj.(*api.Pod).ResourceVersion; e != a {
|
||||
t.Errorf("%v: expected %v, got %v", item.Pod, e, a)
|
||||
}
|
||||
}
|
||||
|
||||
// RV should send the last version we see.
|
||||
if e, a := "32", resumeRV; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
// last sync resource version should be the last version synced with store
|
||||
if e, a := "32", g.LastSyncResourceVersion(); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorWatchHandlerTimeout(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
|
||||
fw := watch.NewFake()
|
||||
var resumeRV string
|
||||
exit := make(chan time.Time, 1)
|
||||
exit <- time.Now()
|
||||
err := g.watchHandler(fw, &resumeRV, exit, wait.NeverStop)
|
||||
if err != errorResyncRequested {
|
||||
t.Errorf("expected timeout error, but got %q", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorStopWatch(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
|
||||
fw := watch.NewFake()
|
||||
var resumeRV string
|
||||
stopWatch := make(chan struct{}, 1)
|
||||
stopWatch <- struct{}{}
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch, stopWatch)
|
||||
if err != errorStopRequested {
|
||||
t.Errorf("expected stop error, got %q", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorListAndWatch(t *testing.T) {
|
||||
createdFakes := make(chan *watch.FakeWatcher)
|
||||
|
||||
// The ListFunc says that it's at revision 1. Therefore, we expect our WatchFunc
|
||||
// to get called at the beginning of the watch with 1, and again with 3 when we
|
||||
// inject an error.
|
||||
expectedRVs := []string{"1", "3"}
|
||||
lw := &testLW{
|
||||
WatchFunc: func(rv string) (watch.Interface, error) {
|
||||
fw := watch.NewFake()
|
||||
if e, a := expectedRVs[0], rv; e != a {
|
||||
t.Errorf("Expected rv %v, but got %v", e, a)
|
||||
}
|
||||
expectedRVs = expectedRVs[1:]
|
||||
// channel is not buffered because the for loop below needs to block. But
|
||||
// we don't want to block here, so report the new fake via a go routine.
|
||||
go func() { createdFakes <- fw }()
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func() (runtime.Object, error) {
|
||||
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "1"}}, nil
|
||||
},
|
||||
}
|
||||
s := NewFIFO(MetaNamespaceKeyFunc)
|
||||
r := NewReflector(lw, &api.Pod{}, s, 0)
|
||||
go r.ListAndWatch(wait.NeverStop)
|
||||
|
||||
ids := []string{"foo", "bar", "baz", "qux", "zoo"}
|
||||
var fw *watch.FakeWatcher
|
||||
for i, id := range ids {
|
||||
if fw == nil {
|
||||
fw = <-createdFakes
|
||||
}
|
||||
sendingRV := strconv.FormatUint(uint64(i+2), 10)
|
||||
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: sendingRV}})
|
||||
if sendingRV == "3" {
|
||||
// Inject a failure.
|
||||
fw.Stop()
|
||||
fw = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Verify we received the right ids with the right resource versions.
|
||||
for i, id := range ids {
|
||||
pod := s.Pop().(*api.Pod)
|
||||
if e, a := id, pod.Name; e != a {
|
||||
t.Errorf("%v: Expected %v, got %v", i, e, a)
|
||||
}
|
||||
if e, a := strconv.FormatUint(uint64(i+2), 10), pod.ResourceVersion; e != a {
|
||||
t.Errorf("%v: Expected %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
|
||||
if len(expectedRVs) != 0 {
|
||||
t.Error("called watchStarter an unexpected number of times")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorListAndWatchWithErrors(t *testing.T) {
|
||||
mkPod := func(id string, rv string) *api.Pod {
|
||||
return &api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: rv}}
|
||||
}
|
||||
mkList := func(rv string, pods ...*api.Pod) *api.PodList {
|
||||
list := &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: rv}}
|
||||
for _, pod := range pods {
|
||||
list.Items = append(list.Items, *pod)
|
||||
}
|
||||
return list
|
||||
}
|
||||
table := []struct {
|
||||
list *api.PodList
|
||||
listErr error
|
||||
events []watch.Event
|
||||
watchErr error
|
||||
}{
|
||||
{
|
||||
list: mkList("1"),
|
||||
events: []watch.Event{
|
||||
{watch.Added, mkPod("foo", "2")},
|
||||
{watch.Added, mkPod("bar", "3")},
|
||||
},
|
||||
}, {
|
||||
list: mkList("3", mkPod("foo", "2"), mkPod("bar", "3")),
|
||||
events: []watch.Event{
|
||||
{watch.Deleted, mkPod("foo", "4")},
|
||||
{watch.Added, mkPod("qux", "5")},
|
||||
},
|
||||
}, {
|
||||
listErr: fmt.Errorf("a list error"),
|
||||
}, {
|
||||
list: mkList("5", mkPod("bar", "3"), mkPod("qux", "5")),
|
||||
watchErr: fmt.Errorf("a watch error"),
|
||||
}, {
|
||||
list: mkList("5", mkPod("bar", "3"), mkPod("qux", "5")),
|
||||
events: []watch.Event{
|
||||
{watch.Added, mkPod("baz", "6")},
|
||||
},
|
||||
}, {
|
||||
list: mkList("6", mkPod("bar", "3"), mkPod("qux", "5"), mkPod("baz", "6")),
|
||||
},
|
||||
}
|
||||
|
||||
s := NewFIFO(MetaNamespaceKeyFunc)
|
||||
for line, item := range table {
|
||||
if item.list != nil {
|
||||
// Test that the list is what currently exists in the store.
|
||||
current := s.List()
|
||||
checkMap := map[string]string{}
|
||||
for _, item := range current {
|
||||
pod := item.(*api.Pod)
|
||||
checkMap[pod.Name] = pod.ResourceVersion
|
||||
}
|
||||
for _, pod := range item.list.Items {
|
||||
if e, a := pod.ResourceVersion, checkMap[pod.Name]; e != a {
|
||||
t.Errorf("%v: expected %v, got %v for pod %v", line, e, a, pod.Name)
|
||||
}
|
||||
}
|
||||
if e, a := len(item.list.Items), len(checkMap); e != a {
|
||||
t.Errorf("%v: expected %v, got %v", line, e, a)
|
||||
}
|
||||
}
|
||||
watchRet, watchErr := item.events, item.watchErr
|
||||
lw := &testLW{
|
||||
WatchFunc: func(rv string) (watch.Interface, error) {
|
||||
if watchErr != nil {
|
||||
return nil, watchErr
|
||||
}
|
||||
watchErr = fmt.Errorf("second watch")
|
||||
fw := watch.NewFake()
|
||||
go func() {
|
||||
for _, e := range watchRet {
|
||||
fw.Action(e.Type, e.Object)
|
||||
}
|
||||
fw.Stop()
|
||||
}()
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func() (runtime.Object, error) {
|
||||
return item.list, item.listErr
|
||||
},
|
||||
}
|
||||
r := NewReflector(lw, &api.Pod{}, s, 0)
|
||||
r.ListAndWatch(wait.NeverStop)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorResync(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
|
||||
currentTime := time.Time{}
|
||||
iteration := 0
|
||||
|
||||
lw := &testLW{
|
||||
WatchFunc: func(rv string) (watch.Interface, error) {
|
||||
if iteration == 0 {
|
||||
// Move time, but do not force resync.
|
||||
currentTime = currentTime.Add(30 * time.Second)
|
||||
} else if iteration == 1 {
|
||||
// Move time to force resync.
|
||||
currentTime = currentTime.Add(28 * time.Second)
|
||||
} else if iteration >= 2 {
|
||||
t.Fatalf("should have forced resync earlier")
|
||||
}
|
||||
iteration++
|
||||
fw := watch.NewFake()
|
||||
// Send something to the watcher to avoid "watch too short" errors.
|
||||
go func() {
|
||||
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: strconv.Itoa(iteration)}})
|
||||
fw.Stop()
|
||||
}()
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func() (runtime.Object, error) {
|
||||
return &api.PodList{ListMeta: unversioned.ListMeta{ResourceVersion: "0"}}, nil
|
||||
},
|
||||
}
|
||||
resyncPeriod := time.Minute
|
||||
r := NewReflector(lw, &api.Pod{}, s, resyncPeriod)
|
||||
r.now = func() time.Time { return currentTime }
|
||||
|
||||
r.ListAndWatch(wait.NeverStop)
|
||||
if iteration != 2 {
|
||||
t.Errorf("exactly 2 iterations were expected, got: %v", iteration)
|
||||
}
|
||||
}
|
||||
225
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/store.go
generated
vendored
Normal file
225
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/store.go
generated
vendored
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
)
|
||||
|
||||
// Store is a generic object storage interface. Reflector knows how to watch a server
|
||||
// and update a store. A generic store is provided, which allows Reflector to be used
|
||||
// as a local caching system, and an LRU store, which allows Reflector to work like a
|
||||
// queue of items yet to be processed.
|
||||
//
|
||||
// Store makes no assumptions about stored object identity; it is the responsibility
|
||||
// of a Store implementation to provide a mechanism to correctly key objects and to
|
||||
// define the contract for obtaining objects by some arbitrary key type.
|
||||
type Store interface {
|
||||
Add(obj interface{}) error
|
||||
Update(obj interface{}) error
|
||||
Delete(obj interface{}) error
|
||||
List() []interface{}
|
||||
ListKeys() []string
|
||||
Get(obj interface{}) (item interface{}, exists bool, err error)
|
||||
GetByKey(key string) (item interface{}, exists bool, err error)
|
||||
|
||||
// Replace will delete the contents of the store, using instead the
|
||||
// given list. Store takes ownership of the list, you should not reference
|
||||
// it after calling this function.
|
||||
Replace([]interface{}, string) error
|
||||
}
|
||||
|
||||
// KeyFunc knows how to make a key from an object. Implementations should be deterministic.
|
||||
type KeyFunc func(obj interface{}) (string, error)
|
||||
|
||||
// KeyError will be returned any time a KeyFunc gives an error; it includes the object
|
||||
// at fault.
|
||||
type KeyError struct {
|
||||
Obj interface{}
|
||||
Err error
|
||||
}
|
||||
|
||||
// Error gives a human-readable description of the error.
|
||||
func (k KeyError) Error() string {
|
||||
return fmt.Sprintf("couldn't create key for object %+v: %v", k.Obj, k.Err)
|
||||
}
|
||||
|
||||
// ExplicitKey can be passed to MetaNamespaceKeyFunc if you have the key for
|
||||
// the object but not the object itself.
|
||||
type ExplicitKey string
|
||||
|
||||
// MetaNamespaceKeyFunc is a convenient default KeyFunc which knows how to make
|
||||
// keys for API objects which implement meta.Interface.
|
||||
// The key uses the format <namespace>/<name> unless <namespace> is empty, then
|
||||
// it's just <name>.
|
||||
//
|
||||
// TODO: replace key-as-string with a key-as-struct so that this
|
||||
// packing/unpacking won't be necessary.
|
||||
func MetaNamespaceKeyFunc(obj interface{}) (string, error) {
|
||||
if key, ok := obj.(ExplicitKey); ok {
|
||||
return string(key), nil
|
||||
}
|
||||
meta, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("object has no meta: %v", err)
|
||||
}
|
||||
if len(meta.GetNamespace()) > 0 {
|
||||
return meta.GetNamespace() + "/" + meta.GetName(), nil
|
||||
}
|
||||
return meta.GetName(), nil
|
||||
}
|
||||
|
||||
// SplitMetaNamespaceKey returns the namespace and name that
|
||||
// MetaNamespaceKeyFunc encoded into key.
|
||||
//
|
||||
// TODO: replace key-as-string with a key-as-struct so that this
|
||||
// packing/unpacking won't be necessary.
|
||||
func SplitMetaNamespaceKey(key string) (namespace, name string, err error) {
|
||||
parts := strings.Split(key, "/")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
// name only, no namespace
|
||||
return "", parts[0], nil
|
||||
case 2:
|
||||
// name and namespace
|
||||
return parts[0], parts[1], nil
|
||||
}
|
||||
|
||||
return "", "", fmt.Errorf("unexpected key format: %q", key)
|
||||
}
|
||||
|
||||
// cache responsibilities are limited to:
|
||||
// 1. Computing keys for objects via keyFunc
|
||||
// 2. Invoking methods of a ThreadSafeStorage interface
|
||||
type cache struct {
|
||||
// cacheStorage bears the burden of thread safety for the cache
|
||||
cacheStorage ThreadSafeStore
|
||||
// keyFunc is used to make the key for objects stored in and retrieved from items, and
|
||||
// should be deterministic.
|
||||
keyFunc KeyFunc
|
||||
}
|
||||
|
||||
var _ Store = &cache{}
|
||||
|
||||
// Add inserts an item into the cache.
|
||||
func (c *cache) Add(obj interface{}) error {
|
||||
key, err := c.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
c.cacheStorage.Add(key, obj)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update sets an item in the cache to its updated state.
|
||||
func (c *cache) Update(obj interface{}) error {
|
||||
key, err := c.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
c.cacheStorage.Update(key, obj)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete removes an item from the cache.
|
||||
func (c *cache) Delete(obj interface{}) error {
|
||||
key, err := c.keyFunc(obj)
|
||||
if err != nil {
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
c.cacheStorage.Delete(key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns a list of all the items.
|
||||
// List is completely threadsafe as long as you treat all items as immutable.
|
||||
func (c *cache) List() []interface{} {
|
||||
return c.cacheStorage.List()
|
||||
}
|
||||
|
||||
// ListKeys returns a list of all the keys of the objects currently
|
||||
// in the cache.
|
||||
func (c *cache) ListKeys() []string {
|
||||
return c.cacheStorage.ListKeys()
|
||||
}
|
||||
|
||||
// Index returns a list of items that match on the index function
|
||||
// Index is thread-safe so long as you treat all items as immutable
|
||||
func (c *cache) Index(indexName string, obj interface{}) ([]interface{}, error) {
|
||||
return c.cacheStorage.Index(indexName, obj)
|
||||
}
|
||||
|
||||
// ListIndexFuncValues returns the list of generated values of an Index func
|
||||
func (c *cache) ListIndexFuncValues(indexName string) []string {
|
||||
return c.cacheStorage.ListIndexFuncValues(indexName)
|
||||
}
|
||||
|
||||
func (c *cache) ByIndex(indexName, indexKey string) ([]interface{}, error) {
|
||||
return c.cacheStorage.ByIndex(indexName, indexKey)
|
||||
}
|
||||
|
||||
// Get returns the requested item, or sets exists=false.
|
||||
// Get is completely threadsafe as long as you treat all items as immutable.
|
||||
func (c *cache) Get(obj interface{}) (item interface{}, exists bool, err error) {
|
||||
key, err := c.keyFunc(obj)
|
||||
if err != nil {
|
||||
return nil, false, KeyError{obj, err}
|
||||
}
|
||||
return c.GetByKey(key)
|
||||
}
|
||||
|
||||
// GetByKey returns the request item, or exists=false.
|
||||
// GetByKey is completely threadsafe as long as you treat all items as immutable.
|
||||
func (c *cache) GetByKey(key string) (item interface{}, exists bool, err error) {
|
||||
item, exists = c.cacheStorage.Get(key)
|
||||
return item, exists, nil
|
||||
}
|
||||
|
||||
// Replace will delete the contents of 'c', using instead the given list.
|
||||
// 'c' takes ownership of the list, you should not reference the list again
|
||||
// after calling this function.
|
||||
func (c *cache) Replace(list []interface{}, resourceVersion string) error {
|
||||
items := map[string]interface{}{}
|
||||
for _, item := range list {
|
||||
key, err := c.keyFunc(item)
|
||||
if err != nil {
|
||||
return KeyError{item, err}
|
||||
}
|
||||
items[key] = item
|
||||
}
|
||||
c.cacheStorage.Replace(items, resourceVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewStore returns a Store implemented simply with a map and a lock.
|
||||
func NewStore(keyFunc KeyFunc) Store {
|
||||
return &cache{
|
||||
cacheStorage: NewThreadSafeStore(Indexers{}, Indices{}),
|
||||
keyFunc: keyFunc,
|
||||
}
|
||||
}
|
||||
|
||||
// NewIndexer returns an Indexer implemented simply with a map and a lock.
|
||||
func NewIndexer(keyFunc KeyFunc, indexers Indexers) Indexer {
|
||||
return &cache{
|
||||
cacheStorage: NewThreadSafeStore(indexers, Indices{}),
|
||||
keyFunc: keyFunc,
|
||||
}
|
||||
}
|
||||
156
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/store_test.go
generated
vendored
Normal file
156
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/store_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
||||
// Test public interface
|
||||
func doTestStore(t *testing.T, store Store) {
|
||||
mkObj := func(id string, val string) testStoreObject {
|
||||
return testStoreObject{id: id, val: val}
|
||||
}
|
||||
|
||||
store.Add(mkObj("foo", "bar"))
|
||||
if item, ok, _ := store.Get(mkObj("foo", "")); !ok {
|
||||
t.Errorf("didn't find inserted item")
|
||||
} else {
|
||||
if e, a := "bar", item.(testStoreObject).val; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
store.Update(mkObj("foo", "baz"))
|
||||
if item, ok, _ := store.Get(mkObj("foo", "")); !ok {
|
||||
t.Errorf("didn't find inserted item")
|
||||
} else {
|
||||
if e, a := "baz", item.(testStoreObject).val; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
store.Delete(mkObj("foo", ""))
|
||||
if _, ok, _ := store.Get(mkObj("foo", "")); ok {
|
||||
t.Errorf("found deleted item??")
|
||||
}
|
||||
|
||||
// Test List.
|
||||
store.Add(mkObj("a", "b"))
|
||||
store.Add(mkObj("c", "d"))
|
||||
store.Add(mkObj("e", "e"))
|
||||
{
|
||||
found := sets.String{}
|
||||
for _, item := range store.List() {
|
||||
found.Insert(item.(testStoreObject).val)
|
||||
}
|
||||
if !found.HasAll("b", "d", "e") {
|
||||
t.Errorf("missing items, found: %v", found)
|
||||
}
|
||||
if len(found) != 3 {
|
||||
t.Errorf("extra items")
|
||||
}
|
||||
}
|
||||
|
||||
// Test Replace.
|
||||
store.Replace([]interface{}{
|
||||
mkObj("foo", "foo"),
|
||||
mkObj("bar", "bar"),
|
||||
}, "0")
|
||||
|
||||
{
|
||||
found := sets.String{}
|
||||
for _, item := range store.List() {
|
||||
found.Insert(item.(testStoreObject).val)
|
||||
}
|
||||
if !found.HasAll("foo", "bar") {
|
||||
t.Errorf("missing items")
|
||||
}
|
||||
if len(found) != 2 {
|
||||
t.Errorf("extra items")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test public interface
|
||||
func doTestIndex(t *testing.T, indexer Indexer) {
|
||||
mkObj := func(id string, val string) testStoreObject {
|
||||
return testStoreObject{id: id, val: val}
|
||||
}
|
||||
|
||||
// Test Index
|
||||
expected := map[string]sets.String{}
|
||||
expected["b"] = sets.NewString("a", "c")
|
||||
expected["f"] = sets.NewString("e")
|
||||
expected["h"] = sets.NewString("g")
|
||||
indexer.Add(mkObj("a", "b"))
|
||||
indexer.Add(mkObj("c", "b"))
|
||||
indexer.Add(mkObj("e", "f"))
|
||||
indexer.Add(mkObj("g", "h"))
|
||||
{
|
||||
for k, v := range expected {
|
||||
found := sets.String{}
|
||||
indexResults, err := indexer.Index("by_val", mkObj("", k))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %v", err)
|
||||
}
|
||||
for _, item := range indexResults {
|
||||
found.Insert(item.(testStoreObject).id)
|
||||
}
|
||||
items := v.List()
|
||||
if !found.HasAll(items...) {
|
||||
t.Errorf("missing items, index %s, expected %v but found %v", k, items, found.List())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testStoreKeyFunc(obj interface{}) (string, error) {
|
||||
return obj.(testStoreObject).id, nil
|
||||
}
|
||||
|
||||
func testStoreIndexFunc(obj interface{}) ([]string, error) {
|
||||
return []string{obj.(testStoreObject).val}, nil
|
||||
}
|
||||
|
||||
func testStoreIndexers() Indexers {
|
||||
indexers := Indexers{}
|
||||
indexers["by_val"] = testStoreIndexFunc
|
||||
return indexers
|
||||
}
|
||||
|
||||
type testStoreObject struct {
|
||||
id string
|
||||
val string
|
||||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
doTestStore(t, NewStore(testStoreKeyFunc))
|
||||
}
|
||||
|
||||
func TestFIFOCache(t *testing.T) {
|
||||
doTestStore(t, NewFIFO(testStoreKeyFunc))
|
||||
}
|
||||
|
||||
func TestUndeltaStore(t *testing.T) {
|
||||
nop := func([]interface{}) {}
|
||||
doTestStore(t, NewUndeltaStore(nop, testStoreKeyFunc))
|
||||
}
|
||||
|
||||
func TestIndex(t *testing.T) {
|
||||
doTestIndex(t, NewIndexer(testStoreKeyFunc, testStoreIndexers()))
|
||||
}
|
||||
248
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go
generated
vendored
Normal file
248
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go
generated
vendored
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
||||
// ThreadSafeStore is an interface that allows concurrent access to a storage backend.
|
||||
// TL;DR caveats: you must not modify anything returned by Get or List as it will break
|
||||
// the indexing feature in addition to not being thread safe.
|
||||
//
|
||||
// The guarantees of thread safety provided by List/Get are only valid if the caller
|
||||
// treats returned items as read-only. For example, a pointer inserted in the store
|
||||
// through `Add` will be returned as is by `Get`. Multiple clients might invoke `Get`
|
||||
// on the same key and modify the pointer in a non-thread-safe way. Also note that
|
||||
// modifying objects stored by the indexers (if any) will *not* automatically lead
|
||||
// to a re-index. So it's not a good idea to directly modify the objects returned by
|
||||
// Get/List, in general.
|
||||
type ThreadSafeStore interface {
|
||||
Add(key string, obj interface{})
|
||||
Update(key string, obj interface{})
|
||||
Delete(key string)
|
||||
Get(key string) (item interface{}, exists bool)
|
||||
List() []interface{}
|
||||
ListKeys() []string
|
||||
Replace(map[string]interface{}, string)
|
||||
Index(indexName string, obj interface{}) ([]interface{}, error)
|
||||
ListIndexFuncValues(name string) []string
|
||||
ByIndex(indexName, indexKey string) ([]interface{}, error)
|
||||
}
|
||||
|
||||
// threadSafeMap implements ThreadSafeStore
|
||||
type threadSafeMap struct {
|
||||
lock sync.RWMutex
|
||||
items map[string]interface{}
|
||||
|
||||
// indexers maps a name to an IndexFunc
|
||||
indexers Indexers
|
||||
// indices maps a name to an Index
|
||||
indices Indices
|
||||
}
|
||||
|
||||
func (c *threadSafeMap) Add(key string, obj interface{}) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
oldObject := c.items[key]
|
||||
c.items[key] = obj
|
||||
c.updateIndices(oldObject, obj, key)
|
||||
}
|
||||
|
||||
func (c *threadSafeMap) Update(key string, obj interface{}) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
oldObject := c.items[key]
|
||||
c.items[key] = obj
|
||||
c.updateIndices(oldObject, obj, key)
|
||||
}
|
||||
|
||||
func (c *threadSafeMap) Delete(key string) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if obj, exists := c.items[key]; exists {
|
||||
c.deleteFromIndices(obj, key)
|
||||
delete(c.items, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *threadSafeMap) Get(key string) (item interface{}, exists bool) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
item, exists = c.items[key]
|
||||
return item, exists
|
||||
}
|
||||
|
||||
func (c *threadSafeMap) List() []interface{} {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
list := make([]interface{}, 0, len(c.items))
|
||||
for _, item := range c.items {
|
||||
list = append(list, item)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// ListKeys returns a list of all the keys of the objects currently
|
||||
// in the threadSafeMap.
|
||||
func (c *threadSafeMap) ListKeys() []string {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
list := make([]string, 0, len(c.items))
|
||||
for key := range c.items {
|
||||
list = append(list, key)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func (c *threadSafeMap) Replace(items map[string]interface{}, resourceVersion string) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
c.items = items
|
||||
|
||||
// rebuild any index
|
||||
c.indices = Indices{}
|
||||
for key, item := range c.items {
|
||||
c.updateIndices(nil, item, key)
|
||||
}
|
||||
}
|
||||
|
||||
// Index returns a list of items that match on the index function
|
||||
// Index is thread-safe so long as you treat all items as immutable
|
||||
func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, error) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
indexFunc := c.indexers[indexName]
|
||||
if indexFunc == nil {
|
||||
return nil, fmt.Errorf("Index with name %s does not exist", indexName)
|
||||
}
|
||||
|
||||
indexKeys, err := indexFunc(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
index := c.indices[indexName]
|
||||
|
||||
// need to de-dupe the return list. Since multiple keys are allowed, this can happen.
|
||||
returnKeySet := sets.String{}
|
||||
for _, indexKey := range indexKeys {
|
||||
set := index[indexKey]
|
||||
for _, key := range set.List() {
|
||||
returnKeySet.Insert(key)
|
||||
}
|
||||
}
|
||||
|
||||
list := make([]interface{}, 0, returnKeySet.Len())
|
||||
for absoluteKey := range returnKeySet {
|
||||
list = append(list, c.items[absoluteKey])
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// ByIndex returns a list of items that match an exact value on the index function
|
||||
func (c *threadSafeMap) ByIndex(indexName, indexKey string) ([]interface{}, error) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
indexFunc := c.indexers[indexName]
|
||||
if indexFunc == nil {
|
||||
return nil, fmt.Errorf("Index with name %s does not exist", indexName)
|
||||
}
|
||||
|
||||
index := c.indices[indexName]
|
||||
|
||||
set := index[indexKey]
|
||||
list := make([]interface{}, 0, set.Len())
|
||||
for _, key := range set.List() {
|
||||
list = append(list, c.items[key])
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (c *threadSafeMap) ListIndexFuncValues(indexName string) []string {
|
||||
index := c.indices[indexName]
|
||||
names := make([]string, 0, len(index))
|
||||
for key := range index {
|
||||
names = append(names, key)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// updateIndices modifies the objects location in the managed indexes, if this is an update, you must provide an oldObj
|
||||
// updateIndices must be called from a function that already has a lock on the cache
|
||||
func (c *threadSafeMap) updateIndices(oldObj interface{}, newObj interface{}, key string) error {
|
||||
// if we got an old object, we need to remove it before we add it again
|
||||
if oldObj != nil {
|
||||
c.deleteFromIndices(oldObj, key)
|
||||
}
|
||||
for name, indexFunc := range c.indexers {
|
||||
indexValues, err := indexFunc(newObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
index := c.indices[name]
|
||||
if index == nil {
|
||||
index = Index{}
|
||||
c.indices[name] = index
|
||||
}
|
||||
|
||||
for _, indexValue := range indexValues {
|
||||
set := index[indexValue]
|
||||
if set == nil {
|
||||
set = sets.String{}
|
||||
index[indexValue] = set
|
||||
}
|
||||
set.Insert(key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteFromIndices removes the object from each of the managed indexes
|
||||
// it is intended to be called from a function that already has a lock on the cache
|
||||
func (c *threadSafeMap) deleteFromIndices(obj interface{}, key string) error {
|
||||
for name, indexFunc := range c.indexers {
|
||||
indexValues, err := indexFunc(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
index := c.indices[name]
|
||||
for _, indexValue := range indexValues {
|
||||
if index != nil {
|
||||
set := index[indexValue]
|
||||
if set != nil {
|
||||
set.Delete(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewThreadSafeStore(indexers Indexers, indices Indices) ThreadSafeStore {
|
||||
return &threadSafeMap{
|
||||
items: map[string]interface{}{},
|
||||
indexers: indexers,
|
||||
indices: indices,
|
||||
}
|
||||
}
|
||||
83
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/undelta_store.go
generated
vendored
Normal file
83
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/undelta_store.go
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
// UndeltaStore listens to incremental updates and sends complete state on every change.
|
||||
// It implements the Store interface so that it can receive a stream of mirrored objects
|
||||
// from Reflector. Whenever it receives any complete (Store.Replace) or incremental change
|
||||
// (Store.Add, Store.Update, Store.Delete), it sends the complete state by calling PushFunc.
|
||||
// It is thread-safe. It guarantees that every change (Add, Update, Replace, Delete) results
|
||||
// in one call to PushFunc, but sometimes PushFunc may be called twice with the same values.
|
||||
// PushFunc should be thread safe.
|
||||
type UndeltaStore struct {
|
||||
Store
|
||||
PushFunc func([]interface{})
|
||||
}
|
||||
|
||||
// Assert that it implements the Store interface.
|
||||
var _ Store = &UndeltaStore{}
|
||||
|
||||
// Note about thread safety. The Store implementation (cache.cache) uses a lock for all methods.
|
||||
// In the functions below, the lock gets released and reacquired betweend the {Add,Delete,etc}
|
||||
// and the List. So, the following can happen, resulting in two identical calls to PushFunc.
|
||||
// time thread 1 thread 2
|
||||
// 0 UndeltaStore.Add(a)
|
||||
// 1 UndeltaStore.Add(b)
|
||||
// 2 Store.Add(a)
|
||||
// 3 Store.Add(b)
|
||||
// 4 Store.List() -> [a,b]
|
||||
// 5 Store.List() -> [a,b]
|
||||
|
||||
func (u *UndeltaStore) Add(obj interface{}) error {
|
||||
if err := u.Store.Add(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
u.PushFunc(u.Store.List())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UndeltaStore) Update(obj interface{}) error {
|
||||
if err := u.Store.Update(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
u.PushFunc(u.Store.List())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UndeltaStore) Delete(obj interface{}) error {
|
||||
if err := u.Store.Delete(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
u.PushFunc(u.Store.List())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UndeltaStore) Replace(list []interface{}, resourceVersion string) error {
|
||||
if err := u.Store.Replace(list, resourceVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
u.PushFunc(u.Store.List())
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewUndeltaStore returns an UndeltaStore implemented with a Store.
|
||||
func NewUndeltaStore(pushFunc func([]interface{}), keyFunc KeyFunc) *UndeltaStore {
|
||||
return &UndeltaStore{
|
||||
Store: NewStore(keyFunc),
|
||||
PushFunc: pushFunc,
|
||||
}
|
||||
}
|
||||
131
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/undelta_store_test.go
generated
vendored
Normal file
131
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/cache/undelta_store_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// store_test.go checks that UndeltaStore conforms to the Store interface
|
||||
// behavior. This test just tests that it calls the push func in addition.
|
||||
|
||||
type testUndeltaObject struct {
|
||||
name string
|
||||
val interface{}
|
||||
}
|
||||
|
||||
func testUndeltaKeyFunc(obj interface{}) (string, error) {
|
||||
return obj.(testUndeltaObject).name, nil
|
||||
}
|
||||
|
||||
/*
|
||||
var (
|
||||
o1 interface{} = t{1}
|
||||
o2 interface{} = t{2}
|
||||
l1 []interface{} = []interface{}{t{1}}
|
||||
)
|
||||
*/
|
||||
|
||||
func TestUpdateCallsPush(t *testing.T) {
|
||||
mkObj := func(name string, val interface{}) testUndeltaObject {
|
||||
return testUndeltaObject{name: name, val: val}
|
||||
}
|
||||
|
||||
var got []interface{}
|
||||
var callcount int = 0
|
||||
push := func(m []interface{}) {
|
||||
callcount++
|
||||
got = m
|
||||
}
|
||||
|
||||
u := NewUndeltaStore(push, testUndeltaKeyFunc)
|
||||
|
||||
u.Add(mkObj("a", 2))
|
||||
u.Update(mkObj("a", 1))
|
||||
if callcount != 2 {
|
||||
t.Errorf("Expected 2 calls, got %d", callcount)
|
||||
}
|
||||
|
||||
l := []interface{}{mkObj("a", 1)}
|
||||
if !reflect.DeepEqual(l, got) {
|
||||
t.Errorf("Expected %#v, Got %#v", l, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteCallsPush(t *testing.T) {
|
||||
mkObj := func(name string, val interface{}) testUndeltaObject {
|
||||
return testUndeltaObject{name: name, val: val}
|
||||
}
|
||||
|
||||
var got []interface{}
|
||||
var callcount int = 0
|
||||
push := func(m []interface{}) {
|
||||
callcount++
|
||||
got = m
|
||||
}
|
||||
|
||||
u := NewUndeltaStore(push, testUndeltaKeyFunc)
|
||||
|
||||
u.Add(mkObj("a", 2))
|
||||
u.Delete(mkObj("a", ""))
|
||||
if callcount != 2 {
|
||||
t.Errorf("Expected 2 calls, got %d", callcount)
|
||||
}
|
||||
expected := []interface{}{}
|
||||
if !reflect.DeepEqual(expected, got) {
|
||||
t.Errorf("Expected %#v, Got %#v", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadsDoNotCallPush(t *testing.T) {
|
||||
push := func(m []interface{}) {
|
||||
t.Errorf("Unexpected call to push!")
|
||||
}
|
||||
|
||||
u := NewUndeltaStore(push, testUndeltaKeyFunc)
|
||||
|
||||
// These should not call push.
|
||||
_ = u.List()
|
||||
_, _, _ = u.Get(testUndeltaObject{"a", ""})
|
||||
}
|
||||
|
||||
func TestReplaceCallsPush(t *testing.T) {
|
||||
mkObj := func(name string, val interface{}) testUndeltaObject {
|
||||
return testUndeltaObject{name: name, val: val}
|
||||
}
|
||||
|
||||
var got []interface{}
|
||||
var callcount int = 0
|
||||
push := func(m []interface{}) {
|
||||
callcount++
|
||||
got = m
|
||||
}
|
||||
|
||||
u := NewUndeltaStore(push, testUndeltaKeyFunc)
|
||||
|
||||
m := []interface{}{mkObj("a", 1)}
|
||||
|
||||
u.Replace(m, "0")
|
||||
if callcount != 1 {
|
||||
t.Errorf("Expected 1 calls, got %d", callcount)
|
||||
}
|
||||
expected := []interface{}{mkObj("a", 1)}
|
||||
if !reflect.DeepEqual(expected, got) {
|
||||
t.Errorf("Expected %#v, Got %#v", expected, got)
|
||||
}
|
||||
}
|
||||
94
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset.go
generated
vendored
Normal file
94
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset.go
generated
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 internalclientset
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
unversionedcore "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned"
|
||||
unversionedextensions "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned"
|
||||
unversioned "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Discovery() unversioned.DiscoveryInterface
|
||||
Core() unversionedcore.CoreInterface
|
||||
Extensions() unversionedextensions.ExtensionsInterface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*unversioned.DiscoveryClient
|
||||
*unversionedcore.CoreClient
|
||||
*unversionedextensions.ExtensionsClient
|
||||
}
|
||||
|
||||
// Core retrieves the CoreClient
|
||||
func (c *Clientset) Core() unversionedcore.CoreInterface {
|
||||
return c.CoreClient
|
||||
}
|
||||
|
||||
// Extensions retrieves the ExtensionsClient
|
||||
func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface {
|
||||
return c.ExtensionsClient
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() unversioned.DiscoveryInterface {
|
||||
return c.DiscoveryClient
|
||||
}
|
||||
|
||||
// NewForConfig creates a new Clientset for the given config.
|
||||
func NewForConfig(c *unversioned.Config) (*Clientset, error) {
|
||||
var clientset Clientset
|
||||
var err error
|
||||
clientset.CoreClient, err = unversionedcore.NewForConfig(c)
|
||||
if err != nil {
|
||||
return &clientset, err
|
||||
}
|
||||
clientset.ExtensionsClient, err = unversionedextensions.NewForConfig(c)
|
||||
if err != nil {
|
||||
return &clientset, err
|
||||
}
|
||||
|
||||
clientset.DiscoveryClient, err = unversioned.NewDiscoveryClientForConfig(c)
|
||||
if err != nil {
|
||||
glog.Errorf("failed to create the DiscoveryClient: %v", err)
|
||||
}
|
||||
return &clientset, err
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *unversioned.Config) *Clientset {
|
||||
var clientset Clientset
|
||||
clientset.CoreClient = unversionedcore.NewForConfigOrDie(c)
|
||||
clientset.ExtensionsClient = unversionedextensions.NewForConfigOrDie(c)
|
||||
|
||||
clientset.DiscoveryClient = unversioned.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &clientset
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c *unversioned.RESTClient) *Clientset {
|
||||
var clientset Clientset
|
||||
clientset.CoreClient = unversionedcore.New(c)
|
||||
clientset.ExtensionsClient = unversionedextensions.New(c)
|
||||
|
||||
clientset.DiscoveryClient = unversioned.NewDiscoveryClient(c)
|
||||
return &clientset
|
||||
}
|
||||
42
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset_adaption.go
generated
vendored
Normal file
42
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset_adaption.go
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 internalclientset
|
||||
|
||||
import (
|
||||
unversionedcore "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned"
|
||||
unversionedextensions "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
// FromUnversionedClient adapts a pkg/client/unversioned#Client to a Clientset.
|
||||
// This function is temporary. We will remove it when everyone has moved to using
|
||||
// Clientset. New code should NOT use this function.
|
||||
func FromUnversionedClient(c *unversioned.Client) *Clientset {
|
||||
var clientset Clientset
|
||||
if c != nil {
|
||||
clientset.CoreClient = unversionedcore.New(c.RESTClient)
|
||||
} else {
|
||||
clientset.CoreClient = unversionedcore.New(nil)
|
||||
}
|
||||
if c != nil && c.ExtensionsClient != nil {
|
||||
clientset.ExtensionsClient = unversionedextensions.New(c.ExtensionsClient.RESTClient)
|
||||
} else {
|
||||
clientset.ExtensionsClient = unversionedextensions.New(nil)
|
||||
}
|
||||
|
||||
return &clientset
|
||||
}
|
||||
67
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/metrics/metrics.go
generated
vendored
Normal file
67
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/metrics/metrics.go
generated
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 metrics provides utilities for registering client metrics to Prometheus.
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const restClientSubsystem = "rest_client"
|
||||
|
||||
var (
|
||||
// RequestLatency is a Prometheus Summary metric type partitioned by
|
||||
// "verb" and "url" labels. It is used for the rest client latency metrics.
|
||||
RequestLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: restClientSubsystem,
|
||||
Name: "request_latency_microseconds",
|
||||
Help: "Request latency in microseconds. Broken down by verb and URL",
|
||||
MaxAge: time.Hour,
|
||||
},
|
||||
[]string{"verb", "url"},
|
||||
)
|
||||
|
||||
RequestResult = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: restClientSubsystem,
|
||||
Name: "request_status_codes",
|
||||
Help: "Number of http requests, partitioned by metadata",
|
||||
},
|
||||
[]string{"code", "method", "host"},
|
||||
)
|
||||
)
|
||||
|
||||
var registerMetrics sync.Once
|
||||
|
||||
// Register registers all metrics to Prometheus with
|
||||
// respect to the RequestLatency.
|
||||
func Register() {
|
||||
// Register the metrics.
|
||||
registerMetrics.Do(func() {
|
||||
prometheus.MustRegister(RequestLatency)
|
||||
prometheus.MustRegister(RequestResult)
|
||||
})
|
||||
}
|
||||
|
||||
// Calculates the time since the specified start in microseconds.
|
||||
func SinceInMicroseconds(start time.Time) float64 {
|
||||
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
|
||||
}
|
||||
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/doc.go
generated
vendored
Normal file
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 record has all client logic for recording and reporting events.
|
||||
package record
|
||||
310
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event.go
generated
vendored
Normal file
310
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event.go
generated
vendored
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 record
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const maxTriesPerEvent = 12
|
||||
|
||||
var sleepDuration = 10 * time.Second
|
||||
|
||||
const maxQueuedEvents = 1000
|
||||
|
||||
// EventSink knows how to store events (client.Client implements it.)
|
||||
// EventSink must respect the namespace that will be embedded in 'event'.
|
||||
// It is assumed that EventSink will return the same sorts of errors as
|
||||
// pkg/client's REST client.
|
||||
type EventSink interface {
|
||||
Create(event *api.Event) (*api.Event, error)
|
||||
Update(event *api.Event) (*api.Event, error)
|
||||
Patch(oldEvent *api.Event, data []byte) (*api.Event, error)
|
||||
}
|
||||
|
||||
// EventRecorder knows how to record events on behalf of an EventSource.
|
||||
type EventRecorder interface {
|
||||
// Event constructs an event from the given information and puts it in the queue for sending.
|
||||
// 'object' is the object this event is about. Event will make a reference-- or you may also
|
||||
// pass a reference to the object directly.
|
||||
// 'type' of this event, and can be one of Normal, Warning. New types could be added in future
|
||||
// 'reason' is the reason this event is generated. 'reason' should be short and unique; it
|
||||
// should be in UpperCamelCase format (starting with a capital letter). "reason" will be used
|
||||
// to automate handling of events, so imagine people writing switch statements to handle them.
|
||||
// You want to make that easy.
|
||||
// 'message' is intended to be human readable.
|
||||
//
|
||||
// The resulting event will be created in the same namespace as the reference object.
|
||||
Event(object runtime.Object, eventtype, reason, message string)
|
||||
|
||||
// Eventf is just like Event, but with Sprintf for the message field.
|
||||
Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{})
|
||||
|
||||
// PastEventf is just like Eventf, but with an option to specify the event's 'timestamp' field.
|
||||
PastEventf(object runtime.Object, timestamp unversioned.Time, eventtype, reason, messageFmt string, args ...interface{})
|
||||
}
|
||||
|
||||
// EventBroadcaster knows how to receive events and send them to any EventSink, watcher, or log.
|
||||
type EventBroadcaster interface {
|
||||
// StartEventWatcher starts sending events received from this EventBroadcaster to the given
|
||||
// event handler function. The return value can be ignored or used to stop recording, if
|
||||
// desired.
|
||||
StartEventWatcher(eventHandler func(*api.Event)) watch.Interface
|
||||
|
||||
// StartRecordingToSink starts sending events received from this EventBroadcaster to the given
|
||||
// sink. The return value can be ignored or used to stop recording, if desired.
|
||||
StartRecordingToSink(sink EventSink) watch.Interface
|
||||
|
||||
// StartLogging starts sending events received from this EventBroadcaster to the given logging
|
||||
// function. The return value can be ignored or used to stop recording, if desired.
|
||||
StartLogging(logf func(format string, args ...interface{})) watch.Interface
|
||||
|
||||
// NewRecorder returns an EventRecorder that can be used to send events to this EventBroadcaster
|
||||
// with the event source set to the given event source.
|
||||
NewRecorder(source api.EventSource) EventRecorder
|
||||
}
|
||||
|
||||
// Creates a new event broadcaster.
|
||||
func NewBroadcaster() EventBroadcaster {
|
||||
return &eventBroadcasterImpl{watch.NewBroadcaster(maxQueuedEvents, watch.DropIfChannelFull)}
|
||||
}
|
||||
|
||||
type eventBroadcasterImpl struct {
|
||||
*watch.Broadcaster
|
||||
}
|
||||
|
||||
// StartRecordingToSink starts sending events received from the specified eventBroadcaster to the given sink.
|
||||
// The return value can be ignored or used to stop recording, if desired.
|
||||
// TODO: make me an object with parameterizable queue length and retry interval
|
||||
func (eventBroadcaster *eventBroadcasterImpl) StartRecordingToSink(sink EventSink) watch.Interface {
|
||||
// The default math/rand package functions aren't thread safe, so create a
|
||||
// new Rand object for each StartRecording call.
|
||||
randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
eventCorrelator := NewEventCorrelator(util.RealClock{})
|
||||
return eventBroadcaster.StartEventWatcher(
|
||||
func(event *api.Event) {
|
||||
recordToSink(sink, event, eventCorrelator, randGen)
|
||||
})
|
||||
}
|
||||
|
||||
func recordToSink(sink EventSink, event *api.Event, eventCorrelator *EventCorrelator, randGen *rand.Rand) {
|
||||
// Make a copy before modification, because there could be multiple listeners.
|
||||
// Events are safe to copy like this.
|
||||
eventCopy := *event
|
||||
event = &eventCopy
|
||||
result, err := eventCorrelator.EventCorrelate(event)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
}
|
||||
if result.Skip {
|
||||
return
|
||||
}
|
||||
tries := 0
|
||||
for {
|
||||
if recordEvent(sink, result.Event, result.Patch, result.Event.Count > 1, eventCorrelator) {
|
||||
break
|
||||
}
|
||||
tries++
|
||||
if tries >= maxTriesPerEvent {
|
||||
glog.Errorf("Unable to write event '%#v' (retry limit exceeded!)", event)
|
||||
break
|
||||
}
|
||||
// Randomize the first sleep so that various clients won't all be
|
||||
// synced up if the master goes down.
|
||||
if tries == 1 {
|
||||
time.Sleep(time.Duration(float64(sleepDuration) * randGen.Float64()))
|
||||
} else {
|
||||
time.Sleep(sleepDuration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isKeyNotFoundError(err error) bool {
|
||||
statusErr, _ := err.(*errors.StatusError)
|
||||
// At the moment the server is returning 500 instead of a more specific
|
||||
// error. When changing this remember that it should be backward compatible
|
||||
// with old api servers that may be still returning 500.
|
||||
if statusErr != nil && statusErr.Status().Code == 500 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// recordEvent attempts to write event to a sink. It returns true if the event
|
||||
// was successfully recorded or discarded, false if it should be retried.
|
||||
// If updateExistingEvent is false, it creates a new event, otherwise it updates
|
||||
// existing event.
|
||||
func recordEvent(sink EventSink, event *api.Event, patch []byte, updateExistingEvent bool, eventCorrelator *EventCorrelator) bool {
|
||||
var newEvent *api.Event
|
||||
var err error
|
||||
if updateExistingEvent {
|
||||
newEvent, err = sink.Patch(event, patch)
|
||||
}
|
||||
// Update can fail because the event may have been removed and it no longer exists.
|
||||
if !updateExistingEvent || (updateExistingEvent && isKeyNotFoundError(err)) {
|
||||
// Making sure that ResourceVersion is empty on creation
|
||||
event.ResourceVersion = ""
|
||||
newEvent, err = sink.Create(event)
|
||||
}
|
||||
if err == nil {
|
||||
// we need to update our event correlator with the server returned state to handle name/resourceversion
|
||||
eventCorrelator.UpdateState(newEvent)
|
||||
return true
|
||||
}
|
||||
|
||||
// If we can't contact the server, then hold everything while we keep trying.
|
||||
// Otherwise, something about the event is malformed and we should abandon it.
|
||||
switch err.(type) {
|
||||
case *client.RequestConstructionError:
|
||||
// We will construct the request the same next time, so don't keep trying.
|
||||
glog.Errorf("Unable to construct event '%#v': '%v' (will not retry!)", event, err)
|
||||
return true
|
||||
case *errors.StatusError:
|
||||
if errors.IsAlreadyExists(err) {
|
||||
glog.V(5).Infof("Server rejected event '%#v': '%v' (will not retry!)", event, err)
|
||||
} else {
|
||||
glog.Errorf("Server rejected event '%#v': '%v' (will not retry!)", event, err)
|
||||
}
|
||||
return true
|
||||
case *errors.UnexpectedObjectError:
|
||||
// We don't expect this; it implies the server's response didn't match a
|
||||
// known pattern. Go ahead and retry.
|
||||
default:
|
||||
// This case includes actual http transport errors. Go ahead and retry.
|
||||
}
|
||||
glog.Errorf("Unable to write event: '%v' (may retry after sleeping)", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// StartLogging starts sending events received from this EventBroadcaster to the given logging function.
|
||||
// The return value can be ignored or used to stop recording, if desired.
|
||||
func (eventBroadcaster *eventBroadcasterImpl) StartLogging(logf func(format string, args ...interface{})) watch.Interface {
|
||||
return eventBroadcaster.StartEventWatcher(
|
||||
func(e *api.Event) {
|
||||
logf("Event(%#v): type: '%v' reason: '%v' %v", e.InvolvedObject, e.Type, e.Reason, e.Message)
|
||||
})
|
||||
}
|
||||
|
||||
// StartEventWatcher starts sending events received from this EventBroadcaster to the given event handler function.
|
||||
// The return value can be ignored or used to stop recording, if desired.
|
||||
func (eventBroadcaster *eventBroadcasterImpl) StartEventWatcher(eventHandler func(*api.Event)) watch.Interface {
|
||||
watcher := eventBroadcaster.Watch()
|
||||
go func() {
|
||||
defer utilruntime.HandleCrash()
|
||||
for {
|
||||
watchEvent, open := <-watcher.ResultChan()
|
||||
if !open {
|
||||
return
|
||||
}
|
||||
event, ok := watchEvent.Object.(*api.Event)
|
||||
if !ok {
|
||||
// This is all local, so there's no reason this should
|
||||
// ever happen.
|
||||
continue
|
||||
}
|
||||
eventHandler(event)
|
||||
}
|
||||
}()
|
||||
return watcher
|
||||
}
|
||||
|
||||
// NewRecorder returns an EventRecorder that records events with the given event source.
|
||||
func (eventBroadcaster *eventBroadcasterImpl) NewRecorder(source api.EventSource) EventRecorder {
|
||||
return &recorderImpl{source, eventBroadcaster.Broadcaster, util.RealClock{}}
|
||||
}
|
||||
|
||||
type recorderImpl struct {
|
||||
source api.EventSource
|
||||
*watch.Broadcaster
|
||||
clock util.Clock
|
||||
}
|
||||
|
||||
func (recorder *recorderImpl) generateEvent(object runtime.Object, timestamp unversioned.Time, eventtype, reason, message string) {
|
||||
ref, err := api.GetReference(object)
|
||||
if err != nil {
|
||||
glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v' '%v'", object, err, eventtype, reason, message)
|
||||
return
|
||||
}
|
||||
|
||||
if !validateEventType(eventtype) {
|
||||
glog.Errorf("Unsupported event type: '%v'", eventtype)
|
||||
return
|
||||
}
|
||||
|
||||
event := recorder.makeEvent(ref, eventtype, reason, message)
|
||||
event.Source = recorder.source
|
||||
|
||||
go func() {
|
||||
// NOTE: events should be a non-blocking operation
|
||||
defer utilruntime.HandleCrash()
|
||||
recorder.Action(watch.Added, event)
|
||||
}()
|
||||
}
|
||||
|
||||
func validateEventType(eventtype string) bool {
|
||||
switch eventtype {
|
||||
case api.EventTypeNormal, api.EventTypeWarning:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (recorder *recorderImpl) Event(object runtime.Object, eventtype, reason, message string) {
|
||||
recorder.generateEvent(object, unversioned.Now(), eventtype, reason, message)
|
||||
}
|
||||
|
||||
func (recorder *recorderImpl) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) {
|
||||
recorder.Event(object, eventtype, reason, fmt.Sprintf(messageFmt, args...))
|
||||
}
|
||||
|
||||
func (recorder *recorderImpl) PastEventf(object runtime.Object, timestamp unversioned.Time, eventtype, reason, messageFmt string, args ...interface{}) {
|
||||
recorder.generateEvent(object, timestamp, eventtype, reason, fmt.Sprintf(messageFmt, args...))
|
||||
}
|
||||
|
||||
func (recorder *recorderImpl) makeEvent(ref *api.ObjectReference, eventtype, reason, message string) *api.Event {
|
||||
t := unversioned.Time{recorder.clock.Now()}
|
||||
namespace := ref.Namespace
|
||||
if namespace == "" {
|
||||
namespace = api.NamespaceDefault
|
||||
}
|
||||
return &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: fmt.Sprintf("%v.%x", ref.Name, t.UnixNano()),
|
||||
Namespace: namespace,
|
||||
},
|
||||
InvolvedObject: *ref,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
FirstTimestamp: t,
|
||||
LastTimestamp: t,
|
||||
Count: 1,
|
||||
Type: eventtype,
|
||||
}
|
||||
}
|
||||
885
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event_test.go
generated
vendored
Normal file
885
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/event_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,885 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 record
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
k8sruntime "k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/strategicpatch"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Don't bother sleeping between retries.
|
||||
sleepDuration = 0
|
||||
}
|
||||
|
||||
type testEventSink struct {
|
||||
OnCreate func(e *api.Event) (*api.Event, error)
|
||||
OnUpdate func(e *api.Event) (*api.Event, error)
|
||||
OnPatch func(e *api.Event, p []byte) (*api.Event, error)
|
||||
}
|
||||
|
||||
// CreateEvent records the event for testing.
|
||||
func (t *testEventSink) Create(e *api.Event) (*api.Event, error) {
|
||||
if t.OnCreate != nil {
|
||||
return t.OnCreate(e)
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// UpdateEvent records the event for testing.
|
||||
func (t *testEventSink) Update(e *api.Event) (*api.Event, error) {
|
||||
if t.OnUpdate != nil {
|
||||
return t.OnUpdate(e)
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// PatchEvent records the event for testing.
|
||||
func (t *testEventSink) Patch(e *api.Event, p []byte) (*api.Event, error) {
|
||||
if t.OnPatch != nil {
|
||||
return t.OnPatch(e, p)
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
type OnCreateFunc func(*api.Event) (*api.Event, error)
|
||||
|
||||
func OnCreateFactory(testCache map[string]*api.Event, createEvent chan<- *api.Event) OnCreateFunc {
|
||||
return func(event *api.Event) (*api.Event, error) {
|
||||
testCache[getEventKey(event)] = event
|
||||
createEvent <- event
|
||||
return event, nil
|
||||
}
|
||||
}
|
||||
|
||||
type OnPatchFunc func(*api.Event, []byte) (*api.Event, error)
|
||||
|
||||
func OnPatchFactory(testCache map[string]*api.Event, patchEvent chan<- *api.Event) OnPatchFunc {
|
||||
return func(event *api.Event, patch []byte) (*api.Event, error) {
|
||||
cachedEvent, found := testCache[getEventKey(event)]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unexpected error: couldn't find Event in testCache.")
|
||||
}
|
||||
originalData, err := json.Marshal(cachedEvent)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
patched, err := strategicpatch.StrategicMergePatch(originalData, patch, event)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
patchedObj := &api.Event{}
|
||||
err = json.Unmarshal(patched, patchedObj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
patchEvent <- patchedObj
|
||||
return patchedObj, nil
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventf(t *testing.T) {
|
||||
testPod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
SelfLink: "/api/version/pods/foo",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
},
|
||||
}
|
||||
testPod2 := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
SelfLink: "/api/version/pods/foo",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
},
|
||||
}
|
||||
testRef, err := api.GetPartialReference(testPod, "spec.containers[2]")
|
||||
testRef2, err := api.GetPartialReference(testPod2, "spec.containers[3]")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
table := []struct {
|
||||
obj k8sruntime.Object
|
||||
eventtype string
|
||||
reason string
|
||||
messageFmt string
|
||||
elements []interface{}
|
||||
expect *api.Event
|
||||
expectLog string
|
||||
expectUpdate bool
|
||||
}{
|
||||
{
|
||||
obj: testRef,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[2]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testPod,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Killed",
|
||||
messageFmt: "some other verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
},
|
||||
Reason: "Killed",
|
||||
Message: "some other verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'Killed' some other verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testRef,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[2]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 2,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: true,
|
||||
},
|
||||
{
|
||||
obj: testRef2,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[3]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testRef,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[2]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 3,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: true,
|
||||
},
|
||||
{
|
||||
obj: testRef2,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Stopped",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[3]",
|
||||
},
|
||||
Reason: "Stopped",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testRef2,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Stopped",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[3]",
|
||||
},
|
||||
Reason: "Stopped",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 2,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
|
||||
expectUpdate: true,
|
||||
},
|
||||
}
|
||||
|
||||
testCache := map[string]*api.Event{}
|
||||
logCalled := make(chan struct{})
|
||||
createEvent := make(chan *api.Event)
|
||||
updateEvent := make(chan *api.Event)
|
||||
patchEvent := make(chan *api.Event)
|
||||
testEvents := testEventSink{
|
||||
OnCreate: OnCreateFactory(testCache, createEvent),
|
||||
OnUpdate: func(event *api.Event) (*api.Event, error) {
|
||||
updateEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
OnPatch: OnPatchFactory(testCache, patchEvent),
|
||||
}
|
||||
eventBroadcaster := NewBroadcaster()
|
||||
sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents)
|
||||
|
||||
clock := util.NewFakeClock(time.Now())
|
||||
recorder := recorderWithFakeClock(api.EventSource{Component: "eventTest"}, eventBroadcaster, clock)
|
||||
for index, item := range table {
|
||||
clock.Step(1 * time.Second)
|
||||
logWatcher1 := eventBroadcaster.StartLogging(t.Logf) // Prove that it is useful
|
||||
logWatcher2 := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) {
|
||||
if e, a := item.expectLog, fmt.Sprintf(formatter, args...); e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
logCalled <- struct{}{}
|
||||
})
|
||||
recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...)
|
||||
|
||||
<-logCalled
|
||||
|
||||
// validate event
|
||||
if item.expectUpdate {
|
||||
actualEvent := <-patchEvent
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
} else {
|
||||
actualEvent := <-createEvent
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
}
|
||||
logWatcher1.Stop()
|
||||
logWatcher2.Stop()
|
||||
}
|
||||
sinkWatcher.Stop()
|
||||
}
|
||||
|
||||
func recorderWithFakeClock(eventSource api.EventSource, eventBroadcaster EventBroadcaster, clock util.Clock) EventRecorder {
|
||||
return &recorderImpl{eventSource, eventBroadcaster.(*eventBroadcasterImpl).Broadcaster, clock}
|
||||
}
|
||||
|
||||
func TestWriteEventError(t *testing.T) {
|
||||
type entry struct {
|
||||
timesToSendError int
|
||||
attemptsWanted int
|
||||
err error
|
||||
}
|
||||
table := map[string]*entry{
|
||||
"giveUp1": {
|
||||
timesToSendError: 1000,
|
||||
attemptsWanted: 1,
|
||||
err: &client.RequestConstructionError{},
|
||||
},
|
||||
"giveUp2": {
|
||||
timesToSendError: 1000,
|
||||
attemptsWanted: 1,
|
||||
err: &errors.StatusError{},
|
||||
},
|
||||
"retry1": {
|
||||
timesToSendError: 1000,
|
||||
attemptsWanted: 12,
|
||||
err: &errors.UnexpectedObjectError{},
|
||||
},
|
||||
"retry2": {
|
||||
timesToSendError: 1000,
|
||||
attemptsWanted: 12,
|
||||
err: fmt.Errorf("A weird error"),
|
||||
},
|
||||
"succeedEventually": {
|
||||
timesToSendError: 2,
|
||||
attemptsWanted: 2,
|
||||
err: fmt.Errorf("A weird error"),
|
||||
},
|
||||
}
|
||||
|
||||
eventCorrelator := NewEventCorrelator(util.RealClock{})
|
||||
randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
for caseName, ent := range table {
|
||||
attempts := 0
|
||||
sink := &testEventSink{
|
||||
OnCreate: func(event *api.Event) (*api.Event, error) {
|
||||
attempts++
|
||||
if attempts < ent.timesToSendError {
|
||||
return nil, ent.err
|
||||
}
|
||||
return event, nil
|
||||
},
|
||||
}
|
||||
ev := &api.Event{}
|
||||
recordToSink(sink, ev, eventCorrelator, randGen)
|
||||
if attempts != ent.attemptsWanted {
|
||||
t.Errorf("case %v: wanted %d, got %d attempts", caseName, ent.attemptsWanted, attempts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLotsOfEvents(t *testing.T) {
|
||||
recorderCalled := make(chan struct{})
|
||||
loggerCalled := make(chan struct{})
|
||||
|
||||
// Fail each event a few times to ensure there's some load on the tested code.
|
||||
var counts [1000]int
|
||||
testEvents := testEventSink{
|
||||
OnCreate: func(event *api.Event) (*api.Event, error) {
|
||||
num, err := strconv.Atoi(event.Message)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return event, nil
|
||||
}
|
||||
counts[num]++
|
||||
if counts[num] < 5 {
|
||||
return nil, fmt.Errorf("fake error")
|
||||
}
|
||||
recorderCalled <- struct{}{}
|
||||
return event, nil
|
||||
},
|
||||
}
|
||||
|
||||
eventBroadcaster := NewBroadcaster()
|
||||
sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents)
|
||||
logWatcher := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) {
|
||||
loggerCalled <- struct{}{}
|
||||
})
|
||||
recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "eventTest"})
|
||||
ref := &api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
}
|
||||
for i := 0; i < maxQueuedEvents; i++ {
|
||||
// we need to vary the reason to prevent aggregation
|
||||
go recorder.Eventf(ref, api.EventTypeNormal, "Reason-"+string(i), strconv.Itoa(i))
|
||||
}
|
||||
// Make sure no events were dropped by either of the listeners.
|
||||
for i := 0; i < maxQueuedEvents; i++ {
|
||||
<-recorderCalled
|
||||
<-loggerCalled
|
||||
}
|
||||
// Make sure that every event was attempted 5 times
|
||||
for i := 0; i < maxQueuedEvents; i++ {
|
||||
if counts[i] < 5 {
|
||||
t.Errorf("Only attempted to record event '%d' %d times.", i, counts[i])
|
||||
}
|
||||
}
|
||||
sinkWatcher.Stop()
|
||||
logWatcher.Stop()
|
||||
}
|
||||
|
||||
func TestEventfNoNamespace(t *testing.T) {
|
||||
testPod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
SelfLink: "/api/version/pods/foo",
|
||||
Name: "foo",
|
||||
UID: "bar",
|
||||
},
|
||||
}
|
||||
testRef, err := api.GetPartialReference(testPod, "spec.containers[2]")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
table := []struct {
|
||||
obj k8sruntime.Object
|
||||
eventtype string
|
||||
reason string
|
||||
messageFmt string
|
||||
elements []interface{}
|
||||
expect *api.Event
|
||||
expectLog string
|
||||
expectUpdate bool
|
||||
}{
|
||||
{
|
||||
obj: testRef,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[2]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
}
|
||||
|
||||
testCache := map[string]*api.Event{}
|
||||
logCalled := make(chan struct{})
|
||||
createEvent := make(chan *api.Event)
|
||||
updateEvent := make(chan *api.Event)
|
||||
patchEvent := make(chan *api.Event)
|
||||
testEvents := testEventSink{
|
||||
OnCreate: OnCreateFactory(testCache, createEvent),
|
||||
OnUpdate: func(event *api.Event) (*api.Event, error) {
|
||||
updateEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
OnPatch: OnPatchFactory(testCache, patchEvent),
|
||||
}
|
||||
eventBroadcaster := NewBroadcaster()
|
||||
sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents)
|
||||
|
||||
clock := util.NewFakeClock(time.Now())
|
||||
recorder := recorderWithFakeClock(api.EventSource{Component: "eventTest"}, eventBroadcaster, clock)
|
||||
|
||||
for index, item := range table {
|
||||
clock.Step(1 * time.Second)
|
||||
logWatcher1 := eventBroadcaster.StartLogging(t.Logf) // Prove that it is useful
|
||||
logWatcher2 := eventBroadcaster.StartLogging(func(formatter string, args ...interface{}) {
|
||||
if e, a := item.expectLog, fmt.Sprintf(formatter, args...); e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
logCalled <- struct{}{}
|
||||
})
|
||||
recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...)
|
||||
|
||||
<-logCalled
|
||||
|
||||
// validate event
|
||||
if item.expectUpdate {
|
||||
actualEvent := <-patchEvent
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
} else {
|
||||
actualEvent := <-createEvent
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
}
|
||||
|
||||
logWatcher1.Stop()
|
||||
logWatcher2.Stop()
|
||||
}
|
||||
sinkWatcher.Stop()
|
||||
}
|
||||
|
||||
func TestMultiSinkCache(t *testing.T) {
|
||||
testPod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
SelfLink: "/api/version/pods/foo",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
},
|
||||
}
|
||||
testPod2 := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
SelfLink: "/api/version/pods/foo",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
},
|
||||
}
|
||||
testRef, err := api.GetPartialReference(testPod, "spec.containers[2]")
|
||||
testRef2, err := api.GetPartialReference(testPod2, "spec.containers[3]")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
table := []struct {
|
||||
obj k8sruntime.Object
|
||||
eventtype string
|
||||
reason string
|
||||
messageFmt string
|
||||
elements []interface{}
|
||||
expect *api.Event
|
||||
expectLog string
|
||||
expectUpdate bool
|
||||
}{
|
||||
{
|
||||
obj: testRef,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[2]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testPod,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Killed",
|
||||
messageFmt: "some other verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
},
|
||||
Reason: "Killed",
|
||||
Message: "some other verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'Killed' some other verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testRef,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[2]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 2,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: true,
|
||||
},
|
||||
{
|
||||
obj: testRef2,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[3]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testRef,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Started",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "bar",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[2]",
|
||||
},
|
||||
Reason: "Started",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 3,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"bar", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[2]"}): type: 'Normal' reason: 'Started' some verbose message: 1`,
|
||||
expectUpdate: true,
|
||||
},
|
||||
{
|
||||
obj: testRef2,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Stopped",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[3]",
|
||||
},
|
||||
Reason: "Stopped",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
|
||||
expectUpdate: false,
|
||||
},
|
||||
{
|
||||
obj: testRef2,
|
||||
eventtype: api.EventTypeNormal,
|
||||
reason: "Stopped",
|
||||
messageFmt: "some verbose message: %v",
|
||||
elements: []interface{}{1},
|
||||
expect: &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Kind: "Pod",
|
||||
Name: "foo",
|
||||
Namespace: "baz",
|
||||
UID: "differentUid",
|
||||
APIVersion: "version",
|
||||
FieldPath: "spec.containers[3]",
|
||||
},
|
||||
Reason: "Stopped",
|
||||
Message: "some verbose message: 1",
|
||||
Source: api.EventSource{Component: "eventTest"},
|
||||
Count: 2,
|
||||
Type: api.EventTypeNormal,
|
||||
},
|
||||
expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"baz", Name:"foo", UID:"differentUid", APIVersion:"version", ResourceVersion:"", FieldPath:"spec.containers[3]"}): type: 'Normal' reason: 'Stopped' some verbose message: 1`,
|
||||
expectUpdate: true,
|
||||
},
|
||||
}
|
||||
|
||||
testCache := map[string]*api.Event{}
|
||||
createEvent := make(chan *api.Event)
|
||||
updateEvent := make(chan *api.Event)
|
||||
patchEvent := make(chan *api.Event)
|
||||
testEvents := testEventSink{
|
||||
OnCreate: OnCreateFactory(testCache, createEvent),
|
||||
OnUpdate: func(event *api.Event) (*api.Event, error) {
|
||||
updateEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
OnPatch: OnPatchFactory(testCache, patchEvent),
|
||||
}
|
||||
|
||||
testCache2 := map[string]*api.Event{}
|
||||
createEvent2 := make(chan *api.Event)
|
||||
updateEvent2 := make(chan *api.Event)
|
||||
patchEvent2 := make(chan *api.Event)
|
||||
testEvents2 := testEventSink{
|
||||
OnCreate: OnCreateFactory(testCache2, createEvent2),
|
||||
OnUpdate: func(event *api.Event) (*api.Event, error) {
|
||||
updateEvent2 <- event
|
||||
return event, nil
|
||||
},
|
||||
OnPatch: OnPatchFactory(testCache2, patchEvent2),
|
||||
}
|
||||
|
||||
eventBroadcaster := NewBroadcaster()
|
||||
clock := util.NewFakeClock(time.Now())
|
||||
recorder := recorderWithFakeClock(api.EventSource{Component: "eventTest"}, eventBroadcaster, clock)
|
||||
|
||||
sinkWatcher := eventBroadcaster.StartRecordingToSink(&testEvents)
|
||||
for index, item := range table {
|
||||
clock.Step(1 * time.Second)
|
||||
recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...)
|
||||
|
||||
// validate event
|
||||
if item.expectUpdate {
|
||||
actualEvent := <-patchEvent
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
} else {
|
||||
actualEvent := <-createEvent
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
}
|
||||
}
|
||||
|
||||
// Another StartRecordingToSink call should start to record events with new clean cache.
|
||||
sinkWatcher2 := eventBroadcaster.StartRecordingToSink(&testEvents2)
|
||||
for index, item := range table {
|
||||
clock.Step(1 * time.Second)
|
||||
recorder.Eventf(item.obj, item.eventtype, item.reason, item.messageFmt, item.elements...)
|
||||
|
||||
// validate event
|
||||
if item.expectUpdate {
|
||||
actualEvent := <-patchEvent2
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
} else {
|
||||
actualEvent := <-createEvent2
|
||||
validateEvent(string(index), actualEvent, item.expect, t)
|
||||
}
|
||||
}
|
||||
|
||||
sinkWatcher.Stop()
|
||||
sinkWatcher2.Stop()
|
||||
}
|
||||
360
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache.go
generated
vendored
Normal file
360
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 record
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/groupcache/lru"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/util/strategicpatch"
|
||||
)
|
||||
|
||||
const (
|
||||
maxLruCacheEntries = 4096
|
||||
|
||||
// if we see the same event that varies only by message
|
||||
// more than 10 times in a 10 minute period, aggregate the event
|
||||
defaultAggregateMaxEvents = 10
|
||||
defaultAggregateIntervalInSeconds = 600
|
||||
)
|
||||
|
||||
// getEventKey builds unique event key based on source, involvedObject, reason, message
|
||||
func getEventKey(event *api.Event) string {
|
||||
return strings.Join([]string{
|
||||
event.Source.Component,
|
||||
event.Source.Host,
|
||||
event.InvolvedObject.Kind,
|
||||
event.InvolvedObject.Namespace,
|
||||
event.InvolvedObject.Name,
|
||||
string(event.InvolvedObject.UID),
|
||||
event.InvolvedObject.APIVersion,
|
||||
event.Type,
|
||||
event.Reason,
|
||||
event.Message,
|
||||
},
|
||||
"")
|
||||
}
|
||||
|
||||
// EventFilterFunc is a function that returns true if the event should be skipped
|
||||
type EventFilterFunc func(event *api.Event) bool
|
||||
|
||||
// DefaultEventFilterFunc returns false for all incoming events
|
||||
func DefaultEventFilterFunc(event *api.Event) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// EventAggregatorKeyFunc is responsible for grouping events for aggregation
|
||||
// It returns a tuple of the following:
|
||||
// aggregateKey - key the identifies the aggregate group to bucket this event
|
||||
// localKey - key that makes this event in the local group
|
||||
type EventAggregatorKeyFunc func(event *api.Event) (aggregateKey string, localKey string)
|
||||
|
||||
// EventAggregatorByReasonFunc aggregates events by exact match on event.Source, event.InvolvedObject, event.Type and event.Reason
|
||||
func EventAggregatorByReasonFunc(event *api.Event) (string, string) {
|
||||
return strings.Join([]string{
|
||||
event.Source.Component,
|
||||
event.Source.Host,
|
||||
event.InvolvedObject.Kind,
|
||||
event.InvolvedObject.Namespace,
|
||||
event.InvolvedObject.Name,
|
||||
string(event.InvolvedObject.UID),
|
||||
event.InvolvedObject.APIVersion,
|
||||
event.Type,
|
||||
event.Reason,
|
||||
},
|
||||
""), event.Message
|
||||
}
|
||||
|
||||
// EventAggregatorMessageFunc is responsible for producing an aggregation message
|
||||
type EventAggregatorMessageFunc func(event *api.Event) string
|
||||
|
||||
// EventAggregratorByReasonMessageFunc returns an aggregate message by prefixing the incoming message
|
||||
func EventAggregatorByReasonMessageFunc(event *api.Event) string {
|
||||
return "(events with common reason combined)"
|
||||
}
|
||||
|
||||
// EventAggregator identifies similar events and aggregates them into a single event
|
||||
type EventAggregator struct {
|
||||
sync.RWMutex
|
||||
|
||||
// The cache that manages aggregation state
|
||||
cache *lru.Cache
|
||||
|
||||
// The function that groups events for aggregation
|
||||
keyFunc EventAggregatorKeyFunc
|
||||
|
||||
// The function that generates a message for an aggregate event
|
||||
messageFunc EventAggregatorMessageFunc
|
||||
|
||||
// The maximum number of events in the specified interval before aggregation occurs
|
||||
maxEvents int
|
||||
|
||||
// The amount of time in seconds that must transpire since the last occurrence of a similar event before it's considered new
|
||||
maxIntervalInSeconds int
|
||||
|
||||
// clock is used to allow for testing over a time interval
|
||||
clock util.Clock
|
||||
}
|
||||
|
||||
// NewEventAggregator returns a new instance of an EventAggregator
|
||||
func NewEventAggregator(lruCacheSize int, keyFunc EventAggregatorKeyFunc, messageFunc EventAggregatorMessageFunc,
|
||||
maxEvents int, maxIntervalInSeconds int, clock util.Clock) *EventAggregator {
|
||||
return &EventAggregator{
|
||||
cache: lru.New(lruCacheSize),
|
||||
keyFunc: keyFunc,
|
||||
messageFunc: messageFunc,
|
||||
maxEvents: maxEvents,
|
||||
maxIntervalInSeconds: maxIntervalInSeconds,
|
||||
clock: clock,
|
||||
}
|
||||
}
|
||||
|
||||
// aggregateRecord holds data used to perform aggregation decisions
|
||||
type aggregateRecord struct {
|
||||
// we track the number of unique local keys we have seen in the aggregate set to know when to actually aggregate
|
||||
// if the size of this set exceeds the max, we know we need to aggregate
|
||||
localKeys sets.String
|
||||
// The last time at which the aggregate was recorded
|
||||
lastTimestamp unversioned.Time
|
||||
}
|
||||
|
||||
// EventAggregate identifies similar events and groups into a common event if required
|
||||
func (e *EventAggregator) EventAggregate(newEvent *api.Event) (*api.Event, error) {
|
||||
aggregateKey, localKey := e.keyFunc(newEvent)
|
||||
now := unversioned.NewTime(e.clock.Now())
|
||||
record := aggregateRecord{localKeys: sets.NewString(), lastTimestamp: now}
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
value, found := e.cache.Get(aggregateKey)
|
||||
if found {
|
||||
record = value.(aggregateRecord)
|
||||
}
|
||||
|
||||
// if the last event was far enough in the past, it is not aggregated, and we must reset state
|
||||
maxInterval := time.Duration(e.maxIntervalInSeconds) * time.Second
|
||||
interval := now.Time.Sub(record.lastTimestamp.Time)
|
||||
if interval > maxInterval {
|
||||
record = aggregateRecord{localKeys: sets.NewString()}
|
||||
}
|
||||
record.localKeys.Insert(localKey)
|
||||
record.lastTimestamp = now
|
||||
e.cache.Add(aggregateKey, record)
|
||||
|
||||
if record.localKeys.Len() < e.maxEvents {
|
||||
return newEvent, nil
|
||||
}
|
||||
|
||||
// do not grow our local key set any larger than max
|
||||
record.localKeys.PopAny()
|
||||
|
||||
// create a new aggregate event
|
||||
eventCopy := &api.Event{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: fmt.Sprintf("%v.%x", newEvent.InvolvedObject.Name, now.UnixNano()),
|
||||
Namespace: newEvent.Namespace,
|
||||
},
|
||||
Count: 1,
|
||||
FirstTimestamp: now,
|
||||
InvolvedObject: newEvent.InvolvedObject,
|
||||
LastTimestamp: now,
|
||||
Message: e.messageFunc(newEvent),
|
||||
Type: newEvent.Type,
|
||||
Reason: newEvent.Reason,
|
||||
Source: newEvent.Source,
|
||||
}
|
||||
return eventCopy, nil
|
||||
}
|
||||
|
||||
// eventLog records data about when an event was observed
|
||||
type eventLog struct {
|
||||
// The number of times the event has occurred since first occurrence.
|
||||
count int
|
||||
|
||||
// The time at which the event was first recorded.
|
||||
firstTimestamp unversioned.Time
|
||||
|
||||
// The unique name of the first occurrence of this event
|
||||
name string
|
||||
|
||||
// Resource version returned from previous interaction with server
|
||||
resourceVersion string
|
||||
}
|
||||
|
||||
// eventLogger logs occurrences of an event
|
||||
type eventLogger struct {
|
||||
sync.RWMutex
|
||||
cache *lru.Cache
|
||||
clock util.Clock
|
||||
}
|
||||
|
||||
// newEventLogger observes events and counts their frequencies
|
||||
func newEventLogger(lruCacheEntries int, clock util.Clock) *eventLogger {
|
||||
return &eventLogger{cache: lru.New(lruCacheEntries), clock: clock}
|
||||
}
|
||||
|
||||
// eventObserve records the event, and determines if its frequency should update
|
||||
func (e *eventLogger) eventObserve(newEvent *api.Event) (*api.Event, []byte, error) {
|
||||
var (
|
||||
patch []byte
|
||||
err error
|
||||
)
|
||||
key := getEventKey(newEvent)
|
||||
eventCopy := *newEvent
|
||||
event := &eventCopy
|
||||
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
|
||||
lastObservation := e.lastEventObservationFromCache(key)
|
||||
|
||||
// we have seen this event before, so we must prepare a patch
|
||||
if lastObservation.count > 0 {
|
||||
// update the event based on the last observation so patch will work as desired
|
||||
event.Name = lastObservation.name
|
||||
event.ResourceVersion = lastObservation.resourceVersion
|
||||
event.FirstTimestamp = lastObservation.firstTimestamp
|
||||
event.Count = lastObservation.count + 1
|
||||
|
||||
eventCopy2 := *event
|
||||
eventCopy2.Count = 0
|
||||
eventCopy2.LastTimestamp = unversioned.NewTime(time.Unix(0, 0))
|
||||
|
||||
newData, _ := json.Marshal(event)
|
||||
oldData, _ := json.Marshal(eventCopy2)
|
||||
patch, err = strategicpatch.CreateStrategicMergePatch(oldData, newData, event)
|
||||
}
|
||||
|
||||
// record our new observation
|
||||
e.cache.Add(
|
||||
key,
|
||||
eventLog{
|
||||
count: event.Count,
|
||||
firstTimestamp: event.FirstTimestamp,
|
||||
name: event.Name,
|
||||
resourceVersion: event.ResourceVersion,
|
||||
},
|
||||
)
|
||||
return event, patch, err
|
||||
}
|
||||
|
||||
// updateState updates its internal tracking information based on latest server state
|
||||
func (e *eventLogger) updateState(event *api.Event) {
|
||||
key := getEventKey(event)
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
// record our new observation
|
||||
e.cache.Add(
|
||||
key,
|
||||
eventLog{
|
||||
count: event.Count,
|
||||
firstTimestamp: event.FirstTimestamp,
|
||||
name: event.Name,
|
||||
resourceVersion: event.ResourceVersion,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// lastEventObservationFromCache returns the event from the cache, reads must be protected via external lock
|
||||
func (e *eventLogger) lastEventObservationFromCache(key string) eventLog {
|
||||
value, ok := e.cache.Get(key)
|
||||
if ok {
|
||||
observationValue, ok := value.(eventLog)
|
||||
if ok {
|
||||
return observationValue
|
||||
}
|
||||
}
|
||||
return eventLog{}
|
||||
}
|
||||
|
||||
// EventCorrelator processes all incoming events and performs analysis to avoid overwhelming the system. It can filter all
|
||||
// incoming events to see if the event should be filtered from further processing. It can aggregate similar events that occur
|
||||
// frequently to protect the system from spamming events that are difficult for users to distinguish. It performs de-duplication
|
||||
// to ensure events that are observed multiple times are compacted into a single event with increasing counts.
|
||||
type EventCorrelator struct {
|
||||
// the function to filter the event
|
||||
filterFunc EventFilterFunc
|
||||
// the object that performs event aggregation
|
||||
aggregator *EventAggregator
|
||||
// the object that observes events as they come through
|
||||
logger *eventLogger
|
||||
}
|
||||
|
||||
// EventCorrelateResult is the result of a Correlate
|
||||
type EventCorrelateResult struct {
|
||||
// the event after correlation
|
||||
Event *api.Event
|
||||
// if provided, perform a strategic patch when updating the record on the server
|
||||
Patch []byte
|
||||
// if true, do no further processing of the event
|
||||
Skip bool
|
||||
}
|
||||
|
||||
// NewEventCorrelator returns an EventCorrelator configured with default values.
|
||||
//
|
||||
// The EventCorrelator is responsible for event filtering, aggregating, and counting
|
||||
// prior to interacting with the API server to record the event.
|
||||
//
|
||||
// The default behavior is as follows:
|
||||
// * No events are filtered from being recorded
|
||||
// * Aggregation is performed if a similar event is recorded 10 times in a
|
||||
// in a 10 minute rolling interval. A similar event is an event that varies only by
|
||||
// the Event.Message field. Rather than recording the precise event, aggregation
|
||||
// will create a new event whose message reports that it has combined events with
|
||||
// the same reason.
|
||||
// * Events are incrementally counted if the exact same event is encountered multiple
|
||||
// times.
|
||||
func NewEventCorrelator(clock util.Clock) *EventCorrelator {
|
||||
cacheSize := maxLruCacheEntries
|
||||
return &EventCorrelator{
|
||||
filterFunc: DefaultEventFilterFunc,
|
||||
aggregator: NewEventAggregator(
|
||||
cacheSize,
|
||||
EventAggregatorByReasonFunc,
|
||||
EventAggregatorByReasonMessageFunc,
|
||||
defaultAggregateMaxEvents,
|
||||
defaultAggregateIntervalInSeconds,
|
||||
clock),
|
||||
logger: newEventLogger(cacheSize, clock),
|
||||
}
|
||||
}
|
||||
|
||||
// EventCorrelate filters, aggregates, counts, and de-duplicates all incoming events
|
||||
func (c *EventCorrelator) EventCorrelate(newEvent *api.Event) (*EventCorrelateResult, error) {
|
||||
if c.filterFunc(newEvent) {
|
||||
return &EventCorrelateResult{Skip: true}, nil
|
||||
}
|
||||
aggregateEvent, err := c.aggregator.EventAggregate(newEvent)
|
||||
if err != nil {
|
||||
return &EventCorrelateResult{}, err
|
||||
}
|
||||
observedEvent, patch, err := c.logger.eventObserve(aggregateEvent)
|
||||
return &EventCorrelateResult{Event: observedEvent, Patch: patch}, err
|
||||
}
|
||||
|
||||
// UpdateState based on the latest observed state from server
|
||||
func (c *EventCorrelator) UpdateState(event *api.Event) {
|
||||
c.logger.updateState(event)
|
||||
}
|
||||
253
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache_test.go
generated
vendored
Normal file
253
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/events_cache_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 record
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
func makeObjectReference(kind, name, namespace string) api.ObjectReference {
|
||||
return api.ObjectReference{
|
||||
Kind: kind,
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
UID: "C934D34AFB20242",
|
||||
APIVersion: "version",
|
||||
}
|
||||
}
|
||||
|
||||
func makeEvent(reason, message string, involvedObject api.ObjectReference) api.Event {
|
||||
eventTime := unversioned.Now()
|
||||
event := api.Event{
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
InvolvedObject: involvedObject,
|
||||
Source: api.EventSource{
|
||||
Component: "kubelet",
|
||||
Host: "kublet.node1",
|
||||
},
|
||||
Count: 1,
|
||||
FirstTimestamp: eventTime,
|
||||
LastTimestamp: eventTime,
|
||||
Type: api.EventTypeNormal,
|
||||
}
|
||||
return event
|
||||
}
|
||||
|
||||
func makeEvents(num int, template api.Event) []api.Event {
|
||||
events := []api.Event{}
|
||||
for i := 0; i < num; i++ {
|
||||
events = append(events, template)
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
func makeUniqueEvents(num int) []api.Event {
|
||||
events := []api.Event{}
|
||||
kind := "Pod"
|
||||
for i := 0; i < num; i++ {
|
||||
reason := strings.Join([]string{"reason", string(i)}, "-")
|
||||
message := strings.Join([]string{"message", string(i)}, "-")
|
||||
name := strings.Join([]string{"pod", string(i)}, "-")
|
||||
namespace := strings.Join([]string{"ns", string(i)}, "-")
|
||||
involvedObject := makeObjectReference(kind, name, namespace)
|
||||
events = append(events, makeEvent(reason, message, involvedObject))
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
func makeSimilarEvents(num int, template api.Event, messagePrefix string) []api.Event {
|
||||
events := makeEvents(num, template)
|
||||
for i := range events {
|
||||
events[i].Message = strings.Join([]string{messagePrefix, string(i), events[i].Message}, "-")
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
||||
func setCount(event api.Event, count int) api.Event {
|
||||
event.Count = count
|
||||
return event
|
||||
}
|
||||
|
||||
func validateEvent(messagePrefix string, actualEvent *api.Event, expectedEvent *api.Event, t *testing.T) (*api.Event, error) {
|
||||
recvEvent := *actualEvent
|
||||
expectCompression := expectedEvent.Count > 1
|
||||
t.Logf("%v - expectedEvent.Count is %d\n", messagePrefix, expectedEvent.Count)
|
||||
// Just check that the timestamp was set.
|
||||
if recvEvent.FirstTimestamp.IsZero() || recvEvent.LastTimestamp.IsZero() {
|
||||
t.Errorf("%v - timestamp wasn't set: %#v", messagePrefix, recvEvent)
|
||||
}
|
||||
actualFirstTimestamp := recvEvent.FirstTimestamp
|
||||
actualLastTimestamp := recvEvent.LastTimestamp
|
||||
if actualFirstTimestamp.Equal(actualLastTimestamp) {
|
||||
if expectCompression {
|
||||
t.Errorf("%v - FirstTimestamp (%q) and LastTimestamp (%q) must be different to indicate event compression happened, but were the same. Actual Event: %#v", messagePrefix, actualFirstTimestamp, actualLastTimestamp, recvEvent)
|
||||
}
|
||||
} else {
|
||||
if expectedEvent.Count == 1 {
|
||||
t.Errorf("%v - FirstTimestamp (%q) and LastTimestamp (%q) must be equal to indicate only one occurrence of the event, but were different. Actual Event: %#v", messagePrefix, actualFirstTimestamp, actualLastTimestamp, recvEvent)
|
||||
}
|
||||
}
|
||||
// Temp clear time stamps for comparison because actual values don't matter for comparison
|
||||
recvEvent.FirstTimestamp = expectedEvent.FirstTimestamp
|
||||
recvEvent.LastTimestamp = expectedEvent.LastTimestamp
|
||||
// Check that name has the right prefix.
|
||||
if n, en := recvEvent.Name, expectedEvent.Name; !strings.HasPrefix(n, en) {
|
||||
t.Errorf("%v - Name '%v' does not contain prefix '%v'", messagePrefix, n, en)
|
||||
}
|
||||
recvEvent.Name = expectedEvent.Name
|
||||
if e, a := expectedEvent, &recvEvent; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v - diff: %s", messagePrefix, util.ObjectGoPrintDiff(e, a))
|
||||
}
|
||||
recvEvent.FirstTimestamp = actualFirstTimestamp
|
||||
recvEvent.LastTimestamp = actualLastTimestamp
|
||||
return actualEvent, nil
|
||||
}
|
||||
|
||||
// TestDefaultEventFilterFunc ensures that no events are filtered
|
||||
func TestDefaultEventFilterFunc(t *testing.T) {
|
||||
event := makeEvent("end-of-world", "it was fun", makeObjectReference("Pod", "pod1", "other"))
|
||||
if DefaultEventFilterFunc(&event) {
|
||||
t.Fatalf("DefaultEventFilterFunc should always return false")
|
||||
}
|
||||
}
|
||||
|
||||
// TestEventAggregatorByReasonFunc ensures that two events are aggregated if they vary only by event.message
|
||||
func TestEventAggregatorByReasonFunc(t *testing.T) {
|
||||
event1 := makeEvent("end-of-world", "it was fun", makeObjectReference("Pod", "pod1", "other"))
|
||||
event2 := makeEvent("end-of-world", "it was awful", makeObjectReference("Pod", "pod1", "other"))
|
||||
event3 := makeEvent("nevermind", "it was a bug", makeObjectReference("Pod", "pod1", "other"))
|
||||
|
||||
aggKey1, localKey1 := EventAggregatorByReasonFunc(&event1)
|
||||
aggKey2, localKey2 := EventAggregatorByReasonFunc(&event2)
|
||||
aggKey3, _ := EventAggregatorByReasonFunc(&event3)
|
||||
|
||||
if aggKey1 != aggKey2 {
|
||||
t.Errorf("Expected %v equal %v", aggKey1, aggKey2)
|
||||
}
|
||||
if localKey1 == localKey2 {
|
||||
t.Errorf("Expected %v to not equal %v", aggKey1, aggKey3)
|
||||
}
|
||||
if aggKey1 == aggKey3 {
|
||||
t.Errorf("Expected %v to not equal %v", aggKey1, aggKey3)
|
||||
}
|
||||
}
|
||||
|
||||
// TestEventAggregatorByReasonMessageFunc validates the proper output for an aggregate message
|
||||
func TestEventAggregatorByReasonMessageFunc(t *testing.T) {
|
||||
expected := "(events with common reason combined)"
|
||||
event1 := makeEvent("end-of-world", "it was fun", makeObjectReference("Pod", "pod1", "other"))
|
||||
if actual := EventAggregatorByReasonMessageFunc(&event1); expected != actual {
|
||||
t.Errorf("Expected %v got %v", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// TestEventCorrelator validates proper counting, aggregation of events
|
||||
func TestEventCorrelator(t *testing.T) {
|
||||
firstEvent := makeEvent("first", "i am first", makeObjectReference("Pod", "my-pod", "my-ns"))
|
||||
duplicateEvent := makeEvent("duplicate", "me again", makeObjectReference("Pod", "my-pod", "my-ns"))
|
||||
uniqueEvent := makeEvent("unique", "snowflake", makeObjectReference("Pod", "my-pod", "my-ns"))
|
||||
similarEvent := makeEvent("similar", "similar message", makeObjectReference("Pod", "my-pod", "my-ns"))
|
||||
aggregateEvent := makeEvent(similarEvent.Reason, EventAggregatorByReasonMessageFunc(&similarEvent), similarEvent.InvolvedObject)
|
||||
scenario := map[string]struct {
|
||||
previousEvents []api.Event
|
||||
newEvent api.Event
|
||||
expectedEvent api.Event
|
||||
intervalSeconds int
|
||||
}{
|
||||
"create-a-single-event": {
|
||||
previousEvents: []api.Event{},
|
||||
newEvent: firstEvent,
|
||||
expectedEvent: setCount(firstEvent, 1),
|
||||
intervalSeconds: 5,
|
||||
},
|
||||
"the-same-event-should-just-count": {
|
||||
previousEvents: makeEvents(1, duplicateEvent),
|
||||
newEvent: duplicateEvent,
|
||||
expectedEvent: setCount(duplicateEvent, 2),
|
||||
intervalSeconds: 5,
|
||||
},
|
||||
"the-same-event-should-just-count-even-if-more-than-aggregate": {
|
||||
previousEvents: makeEvents(defaultAggregateMaxEvents, duplicateEvent),
|
||||
newEvent: duplicateEvent,
|
||||
expectedEvent: setCount(duplicateEvent, defaultAggregateMaxEvents+1),
|
||||
intervalSeconds: 5,
|
||||
},
|
||||
"create-many-unique-events": {
|
||||
previousEvents: makeUniqueEvents(30),
|
||||
newEvent: uniqueEvent,
|
||||
expectedEvent: setCount(uniqueEvent, 1),
|
||||
intervalSeconds: 5,
|
||||
},
|
||||
"similar-events-should-aggregate-event": {
|
||||
previousEvents: makeSimilarEvents(defaultAggregateMaxEvents-1, similarEvent, similarEvent.Message),
|
||||
newEvent: similarEvent,
|
||||
expectedEvent: setCount(aggregateEvent, 1),
|
||||
intervalSeconds: 5,
|
||||
},
|
||||
"similar-events-many-times-should-count-the-aggregate": {
|
||||
previousEvents: makeSimilarEvents(defaultAggregateMaxEvents, similarEvent, similarEvent.Message),
|
||||
newEvent: similarEvent,
|
||||
expectedEvent: setCount(aggregateEvent, 2),
|
||||
intervalSeconds: 5,
|
||||
},
|
||||
"similar-events-whose-interval-is-greater-than-aggregate-interval-do-not-aggregate": {
|
||||
previousEvents: makeSimilarEvents(defaultAggregateMaxEvents-1, similarEvent, similarEvent.Message),
|
||||
newEvent: similarEvent,
|
||||
expectedEvent: setCount(similarEvent, 1),
|
||||
intervalSeconds: defaultAggregateIntervalInSeconds,
|
||||
},
|
||||
}
|
||||
|
||||
for testScenario, testInput := range scenario {
|
||||
eventInterval := time.Duration(testInput.intervalSeconds) * time.Second
|
||||
clock := util.IntervalClock{Time: time.Now(), Duration: eventInterval}
|
||||
correlator := NewEventCorrelator(&clock)
|
||||
for i := range testInput.previousEvents {
|
||||
event := testInput.previousEvents[i]
|
||||
now := unversioned.NewTime(clock.Now())
|
||||
event.FirstTimestamp = now
|
||||
event.LastTimestamp = now
|
||||
result, err := correlator.EventCorrelate(&event)
|
||||
if err != nil {
|
||||
t.Errorf("scenario %v: unexpected error playing back prevEvents %v", testScenario, err)
|
||||
}
|
||||
correlator.UpdateState(result.Event)
|
||||
}
|
||||
|
||||
// update the input to current clock value
|
||||
now := unversioned.NewTime(clock.Now())
|
||||
testInput.newEvent.FirstTimestamp = now
|
||||
testInput.newEvent.LastTimestamp = now
|
||||
result, err := correlator.EventCorrelate(&testInput.newEvent)
|
||||
if err != nil {
|
||||
t.Errorf("scenario %v: unexpected error correlating input event %v", testScenario, err)
|
||||
}
|
||||
|
||||
_, err = validateEvent(testScenario, result.Event, &testInput.expectedEvent, t)
|
||||
if err != nil {
|
||||
t.Errorf("scenario %v: unexpected error validating result %v", testScenario, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/fake.go
generated
vendored
Normal file
40
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/record/fake.go
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 record
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// FakeRecorder is used as a fake during tests.
|
||||
type FakeRecorder struct {
|
||||
Events []string
|
||||
}
|
||||
|
||||
func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) {
|
||||
f.Events = append(f.Events, fmt.Sprintf("%s %s %s", eventtype, reason, message))
|
||||
}
|
||||
|
||||
func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) {
|
||||
f.Events = append(f.Events, fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...))
|
||||
}
|
||||
|
||||
func (f *FakeRecorder) PastEventf(object runtime.Object, timestamp unversioned.Time, eventtype, reason, messageFmt string, args ...interface{}) {
|
||||
}
|
||||
83
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/cache.go
generated
vendored
Normal file
83
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/cache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 transport
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TlsTransportCache caches TLS http.RoundTrippers different configurations. The
|
||||
// same RoundTripper will be returned for configs with identical TLS options If
|
||||
// the config has no custom TLS options, http.DefaultTransport is returned.
|
||||
type tlsTransportCache struct {
|
||||
mu sync.Mutex
|
||||
transports map[string]*http.Transport
|
||||
}
|
||||
|
||||
var tlsCache = &tlsTransportCache{transports: make(map[string]*http.Transport)}
|
||||
|
||||
func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
|
||||
key, err := tlsConfigKey(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Ensure we only create a single transport for the given TLS options
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
// See if we already have a custom transport for this config
|
||||
if t, ok := c.transports[key]; ok {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// Get the TLS options for this client config
|
||||
tlsConfig, err := TLSConfigFor(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// The options didn't require a custom TLS config
|
||||
if tlsConfig == nil {
|
||||
return http.DefaultTransport, nil
|
||||
}
|
||||
|
||||
// Cache a single transport for these options
|
||||
c.transports[key] = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
TLSClientConfig: tlsConfig,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
}
|
||||
return c.transports[key], nil
|
||||
}
|
||||
|
||||
// tlsConfigKey returns a unique key for tls.Config objects returned from TLSConfigFor
|
||||
func tlsConfigKey(c *Config) (string, error) {
|
||||
// Make sure ca/key/cert content is loaded
|
||||
if err := loadTLSFiles(c); err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Only include the things that actually affect the tls.Config
|
||||
return fmt.Sprintf("%v/%x/%x/%x", c.TLS.Insecure, c.TLS.CAData, c.TLS.CertData, c.TLS.KeyData), nil
|
||||
}
|
||||
114
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/cache_test.go
generated
vendored
Normal file
114
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/cache_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 transport
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTLSConfigKey(t *testing.T) {
|
||||
// Make sure config fields that don't affect the tls config don't affect the cache key
|
||||
identicalConfigurations := map[string]*Config{
|
||||
"empty": {},
|
||||
"basic": {Username: "bob", Password: "password"},
|
||||
"bearer": {BearerToken: "token"},
|
||||
"user agent": {UserAgent: "useragent"},
|
||||
"transport": {Transport: http.DefaultTransport},
|
||||
"wrap transport": {WrapTransport: func(http.RoundTripper) http.RoundTripper { return nil }},
|
||||
}
|
||||
for nameA, valueA := range identicalConfigurations {
|
||||
for nameB, valueB := range identicalConfigurations {
|
||||
keyA, err := tlsConfigKey(valueA)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error for %q: %v", nameA, err)
|
||||
continue
|
||||
}
|
||||
keyB, err := tlsConfigKey(valueB)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error for %q: %v", nameB, err)
|
||||
continue
|
||||
}
|
||||
if keyA != keyB {
|
||||
t.Errorf("Expected identical cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure config fields that affect the tls config affect the cache key
|
||||
uniqueConfigurations := map[string]*Config{
|
||||
"no tls": {},
|
||||
"insecure": {TLS: TLSConfig{Insecure: true}},
|
||||
"cadata 1": {TLS: TLSConfig{CAData: []byte{1}}},
|
||||
"cadata 2": {TLS: TLSConfig{CAData: []byte{2}}},
|
||||
"cert 1, key 1": {
|
||||
TLS: TLSConfig{
|
||||
CertData: []byte{1},
|
||||
KeyData: []byte{1},
|
||||
},
|
||||
},
|
||||
"cert 1, key 2": {
|
||||
TLS: TLSConfig{
|
||||
CertData: []byte{1},
|
||||
KeyData: []byte{2},
|
||||
},
|
||||
},
|
||||
"cert 2, key 1": {
|
||||
TLS: TLSConfig{
|
||||
CertData: []byte{2},
|
||||
KeyData: []byte{1},
|
||||
},
|
||||
},
|
||||
"cert 2, key 2": {
|
||||
TLS: TLSConfig{
|
||||
CertData: []byte{2},
|
||||
KeyData: []byte{2},
|
||||
},
|
||||
},
|
||||
"cadata 1, cert 1, key 1": {
|
||||
TLS: TLSConfig{
|
||||
CAData: []byte{1},
|
||||
CertData: []byte{1},
|
||||
KeyData: []byte{1},
|
||||
},
|
||||
},
|
||||
}
|
||||
for nameA, valueA := range uniqueConfigurations {
|
||||
for nameB, valueB := range uniqueConfigurations {
|
||||
// Don't compare to ourselves
|
||||
if nameA == nameB {
|
||||
continue
|
||||
}
|
||||
|
||||
keyA, err := tlsConfigKey(valueA)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error for %q: %v", nameA, err)
|
||||
continue
|
||||
}
|
||||
keyB, err := tlsConfigKey(valueB)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error for %q: %v", nameB, err)
|
||||
continue
|
||||
}
|
||||
if keyA == keyB {
|
||||
t.Errorf("Expected unique cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/config.go
generated
vendored
Normal file
81
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 transport
|
||||
|
||||
import "net/http"
|
||||
|
||||
// Config holds various options for establishing a transport.
|
||||
type Config struct {
|
||||
// UserAgent is an optional field that specifies the caller of this
|
||||
// request.
|
||||
UserAgent string
|
||||
|
||||
// The base TLS configuration for this transport.
|
||||
TLS TLSConfig
|
||||
|
||||
// Username and password for basic authentication
|
||||
Username string
|
||||
Password string
|
||||
|
||||
// Bearer token for authentication
|
||||
BearerToken string
|
||||
|
||||
// Transport may be used for custom HTTP behavior. This attribute may
|
||||
// not be specified with the TLS client certificate options. Use
|
||||
// WrapTransport for most client level operations.
|
||||
Transport http.RoundTripper
|
||||
|
||||
// WrapTransport will be invoked for custom HTTP behavior after the
|
||||
// underlying transport is initialized (either the transport created
|
||||
// from TLSClientConfig, Transport, or http.DefaultTransport). The
|
||||
// config may layer other RoundTrippers on top of the returned
|
||||
// RoundTripper.
|
||||
WrapTransport func(rt http.RoundTripper) http.RoundTripper
|
||||
}
|
||||
|
||||
// HasCA returns whether the configuration has a certificate authority or not.
|
||||
func (c *Config) HasCA() bool {
|
||||
return len(c.TLS.CAData) > 0 || len(c.TLS.CAFile) > 0
|
||||
}
|
||||
|
||||
// HasBasicAuth returns whether the configuration has basic authentication or not.
|
||||
func (c *Config) HasBasicAuth() bool {
|
||||
return len(c.Username) != 0
|
||||
}
|
||||
|
||||
// HasTokenAuth returns whether the configuration has token authentication or not.
|
||||
func (c *Config) HasTokenAuth() bool {
|
||||
return len(c.BearerToken) != 0
|
||||
}
|
||||
|
||||
// HasCertAuth returns whether the configuration has certificate authentication or not.
|
||||
func (c *Config) HasCertAuth() bool {
|
||||
return len(c.TLS.CertData) != 0 || len(c.TLS.CertFile) != 0
|
||||
}
|
||||
|
||||
// TLSConfig holds the information needed to set up a TLS transport.
|
||||
type TLSConfig struct {
|
||||
CAFile string // Path of the PEM-encoded server trusted root certificates.
|
||||
CertFile string // Path of the PEM-encoded client certificate.
|
||||
KeyFile string // Path of the PEM-encoded client key.
|
||||
|
||||
Insecure bool // Server should be accessed without verifying the certificate. For testing only.
|
||||
|
||||
CAData []byte // Bytes of the PEM-encoded server trusted root certificates. Supercedes CAFile.
|
||||
CertData []byte // Bytes of the PEM-encoded client certificate. Supercedes CertFile.
|
||||
KeyData []byte // Bytes of the PEM-encoded client key. Supercedes KeyFile.
|
||||
}
|
||||
305
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/round_trippers.go
generated
vendored
Normal file
305
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/round_trippers.go
generated
vendored
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 transport
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// HTTPWrappersForConfig wraps a round tripper with any relevant layered
|
||||
// behavior from the config. Exposed to allow more clients that need HTTP-like
|
||||
// behavior but then must hijack the underlying connection (like WebSocket or
|
||||
// HTTP2 clients). Pure HTTP clients should use the RoundTripper returned from
|
||||
// New.
|
||||
func HTTPWrappersForConfig(config *Config, rt http.RoundTripper) (http.RoundTripper, error) {
|
||||
if config.WrapTransport != nil {
|
||||
rt = config.WrapTransport(rt)
|
||||
}
|
||||
|
||||
rt = DebugWrappers(rt)
|
||||
|
||||
// Set authentication wrappers
|
||||
switch {
|
||||
case config.HasBasicAuth() && config.HasTokenAuth():
|
||||
return nil, fmt.Errorf("username/password or bearer token may be set, but not both")
|
||||
case config.HasTokenAuth():
|
||||
rt = NewBearerAuthRoundTripper(config.BearerToken, rt)
|
||||
case config.HasBasicAuth():
|
||||
rt = NewBasicAuthRoundTripper(config.Username, config.Password, rt)
|
||||
}
|
||||
if len(config.UserAgent) > 0 {
|
||||
rt = NewUserAgentRoundTripper(config.UserAgent, rt)
|
||||
}
|
||||
return rt, nil
|
||||
}
|
||||
|
||||
// DebugWrappers wraps a round tripper and logs based on the current log level.
|
||||
func DebugWrappers(rt http.RoundTripper) http.RoundTripper {
|
||||
switch {
|
||||
case bool(glog.V(9)):
|
||||
rt = newDebuggingRoundTripper(rt, debugCurlCommand, debugURLTiming, debugResponseHeaders)
|
||||
case bool(glog.V(8)):
|
||||
rt = newDebuggingRoundTripper(rt, debugJustURL, debugRequestHeaders, debugResponseStatus, debugResponseHeaders)
|
||||
case bool(glog.V(7)):
|
||||
rt = newDebuggingRoundTripper(rt, debugJustURL, debugRequestHeaders, debugResponseStatus)
|
||||
case bool(glog.V(6)):
|
||||
rt = newDebuggingRoundTripper(rt, debugURLTiming)
|
||||
}
|
||||
|
||||
return rt
|
||||
}
|
||||
|
||||
type requestCanceler interface {
|
||||
CancelRequest(*http.Request)
|
||||
}
|
||||
|
||||
type userAgentRoundTripper struct {
|
||||
agent string
|
||||
rt http.RoundTripper
|
||||
}
|
||||
|
||||
func NewUserAgentRoundTripper(agent string, rt http.RoundTripper) http.RoundTripper {
|
||||
return &userAgentRoundTripper{agent, rt}
|
||||
}
|
||||
|
||||
func (rt *userAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if len(req.Header.Get("User-Agent")) != 0 {
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
req = cloneRequest(req)
|
||||
req.Header.Set("User-Agent", rt.agent)
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
func (rt *userAgentRoundTripper) CancelRequest(req *http.Request) {
|
||||
if canceler, ok := rt.rt.(requestCanceler); ok {
|
||||
canceler.CancelRequest(req)
|
||||
} else {
|
||||
glog.Errorf("CancelRequest not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *userAgentRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
|
||||
|
||||
type basicAuthRoundTripper struct {
|
||||
username string
|
||||
password string
|
||||
rt http.RoundTripper
|
||||
}
|
||||
|
||||
// NewBasicAuthRoundTripper will apply a BASIC auth authorization header to a
|
||||
// request unless it has already been set.
|
||||
func NewBasicAuthRoundTripper(username, password string, rt http.RoundTripper) http.RoundTripper {
|
||||
return &basicAuthRoundTripper{username, password, rt}
|
||||
}
|
||||
|
||||
func (rt *basicAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if len(req.Header.Get("Authorization")) != 0 {
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
req = cloneRequest(req)
|
||||
req.SetBasicAuth(rt.username, rt.password)
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
func (rt *basicAuthRoundTripper) CancelRequest(req *http.Request) {
|
||||
if canceler, ok := rt.rt.(requestCanceler); ok {
|
||||
canceler.CancelRequest(req)
|
||||
} else {
|
||||
glog.Errorf("CancelRequest not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *basicAuthRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
|
||||
|
||||
type bearerAuthRoundTripper struct {
|
||||
bearer string
|
||||
rt http.RoundTripper
|
||||
}
|
||||
|
||||
// NewBearerAuthRoundTripper adds the provided bearer token to a request
|
||||
// unless the authorization header has already been set.
|
||||
func NewBearerAuthRoundTripper(bearer string, rt http.RoundTripper) http.RoundTripper {
|
||||
return &bearerAuthRoundTripper{bearer, rt}
|
||||
}
|
||||
|
||||
func (rt *bearerAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if len(req.Header.Get("Authorization")) != 0 {
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
req = cloneRequest(req)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", rt.bearer))
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
func (rt *bearerAuthRoundTripper) CancelRequest(req *http.Request) {
|
||||
if canceler, ok := rt.rt.(requestCanceler); ok {
|
||||
canceler.CancelRequest(req)
|
||||
} else {
|
||||
glog.Errorf("CancelRequest not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *bearerAuthRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
|
||||
|
||||
// cloneRequest returns a clone of the provided *http.Request.
|
||||
// The clone is a shallow copy of the struct and its Header map.
|
||||
func cloneRequest(r *http.Request) *http.Request {
|
||||
// shallow copy of the struct
|
||||
r2 := new(http.Request)
|
||||
*r2 = *r
|
||||
// deep copy of the Header
|
||||
r2.Header = make(http.Header)
|
||||
for k, s := range r.Header {
|
||||
r2.Header[k] = s
|
||||
}
|
||||
return r2
|
||||
}
|
||||
|
||||
// requestInfo keeps track of information about a request/response combination
|
||||
type requestInfo struct {
|
||||
RequestHeaders http.Header
|
||||
RequestVerb string
|
||||
RequestURL string
|
||||
|
||||
ResponseStatus string
|
||||
ResponseHeaders http.Header
|
||||
ResponseErr error
|
||||
|
||||
Duration time.Duration
|
||||
}
|
||||
|
||||
// newRequestInfo creates a new RequestInfo based on an http request
|
||||
func newRequestInfo(req *http.Request) *requestInfo {
|
||||
return &requestInfo{
|
||||
RequestURL: req.URL.String(),
|
||||
RequestVerb: req.Method,
|
||||
RequestHeaders: req.Header,
|
||||
}
|
||||
}
|
||||
|
||||
// complete adds information about the response to the requestInfo
|
||||
func (r *requestInfo) complete(response *http.Response, err error) {
|
||||
if err != nil {
|
||||
r.ResponseErr = err
|
||||
return
|
||||
}
|
||||
r.ResponseStatus = response.Status
|
||||
r.ResponseHeaders = response.Header
|
||||
}
|
||||
|
||||
// toCurl returns a string that can be run as a command in a terminal (minus the body)
|
||||
func (r *requestInfo) toCurl() string {
|
||||
headers := ""
|
||||
for key, values := range r.RequestHeaders {
|
||||
for _, value := range values {
|
||||
headers += fmt.Sprintf(` -H %q`, fmt.Sprintf("%s: %s", key, value))
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("curl -k -v -X%s %s %s", r.RequestVerb, headers, r.RequestURL)
|
||||
}
|
||||
|
||||
// debuggingRoundTripper will display information about the requests passing
|
||||
// through it based on what is configured
|
||||
type debuggingRoundTripper struct {
|
||||
delegatedRoundTripper http.RoundTripper
|
||||
|
||||
levels map[debugLevel]bool
|
||||
}
|
||||
|
||||
type debugLevel int
|
||||
|
||||
const (
|
||||
debugJustURL debugLevel = iota
|
||||
debugURLTiming
|
||||
debugCurlCommand
|
||||
debugRequestHeaders
|
||||
debugResponseStatus
|
||||
debugResponseHeaders
|
||||
)
|
||||
|
||||
func newDebuggingRoundTripper(rt http.RoundTripper, levels ...debugLevel) *debuggingRoundTripper {
|
||||
drt := &debuggingRoundTripper{
|
||||
delegatedRoundTripper: rt,
|
||||
levels: make(map[debugLevel]bool, len(levels)),
|
||||
}
|
||||
for _, v := range levels {
|
||||
drt.levels[v] = true
|
||||
}
|
||||
return drt
|
||||
}
|
||||
|
||||
func (rt *debuggingRoundTripper) CancelRequest(req *http.Request) {
|
||||
if canceler, ok := rt.delegatedRoundTripper.(requestCanceler); ok {
|
||||
canceler.CancelRequest(req)
|
||||
} else {
|
||||
glog.Errorf("CancelRequest not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
reqInfo := newRequestInfo(req)
|
||||
|
||||
if rt.levels[debugJustURL] {
|
||||
glog.Infof("%s %s", reqInfo.RequestVerb, reqInfo.RequestURL)
|
||||
}
|
||||
if rt.levels[debugCurlCommand] {
|
||||
glog.Infof("%s", reqInfo.toCurl())
|
||||
|
||||
}
|
||||
if rt.levels[debugRequestHeaders] {
|
||||
glog.Infof("Request Headers:")
|
||||
for key, values := range reqInfo.RequestHeaders {
|
||||
for _, value := range values {
|
||||
glog.Infof(" %s: %s", key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
response, err := rt.delegatedRoundTripper.RoundTrip(req)
|
||||
reqInfo.Duration = time.Since(startTime)
|
||||
|
||||
reqInfo.complete(response, err)
|
||||
|
||||
if rt.levels[debugURLTiming] {
|
||||
glog.Infof("%s %s %s in %d milliseconds", reqInfo.RequestVerb, reqInfo.RequestURL, reqInfo.ResponseStatus, reqInfo.Duration.Nanoseconds()/int64(time.Millisecond))
|
||||
}
|
||||
if rt.levels[debugResponseStatus] {
|
||||
glog.Infof("Response Status: %s in %d milliseconds", reqInfo.ResponseStatus, reqInfo.Duration.Nanoseconds()/int64(time.Millisecond))
|
||||
}
|
||||
if rt.levels[debugResponseHeaders] {
|
||||
glog.Infof("Response Headers:")
|
||||
for key, values := range reqInfo.ResponseHeaders {
|
||||
for _, value := range values {
|
||||
glog.Infof(" %s: %s", key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response, err
|
||||
}
|
||||
|
||||
func (rt *debuggingRoundTripper) WrappedRoundTripper() http.RoundTripper {
|
||||
return rt.delegatedRoundTripper
|
||||
}
|
||||
101
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/round_trippers_test.go
generated
vendored
Normal file
101
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/round_trippers_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 transport
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testRoundTripper struct {
|
||||
Request *http.Request
|
||||
Response *http.Response
|
||||
Err error
|
||||
}
|
||||
|
||||
func (rt *testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
rt.Request = req
|
||||
return rt.Response, rt.Err
|
||||
}
|
||||
|
||||
func TestBearerAuthRoundTripper(t *testing.T) {
|
||||
rt := &testRoundTripper{}
|
||||
req := &http.Request{}
|
||||
NewBearerAuthRoundTripper("test", rt).RoundTrip(req)
|
||||
if rt.Request == nil {
|
||||
t.Fatalf("unexpected nil request: %v", rt)
|
||||
}
|
||||
if rt.Request == req {
|
||||
t.Fatalf("round tripper should have copied request object: %#v", rt.Request)
|
||||
}
|
||||
if rt.Request.Header.Get("Authorization") != "Bearer test" {
|
||||
t.Errorf("unexpected authorization header: %#v", rt.Request)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasicAuthRoundTripper(t *testing.T) {
|
||||
for n, tc := range map[string]struct {
|
||||
user string
|
||||
pass string
|
||||
}{
|
||||
"basic": {user: "user", pass: "pass"},
|
||||
"no pass": {user: "user"},
|
||||
} {
|
||||
rt := &testRoundTripper{}
|
||||
req := &http.Request{}
|
||||
NewBasicAuthRoundTripper(tc.user, tc.pass, rt).RoundTrip(req)
|
||||
if rt.Request == nil {
|
||||
t.Fatalf("%s: unexpected nil request: %v", n, rt)
|
||||
}
|
||||
if rt.Request == req {
|
||||
t.Fatalf("%s: round tripper should have copied request object: %#v", n, rt.Request)
|
||||
}
|
||||
if user, pass, found := rt.Request.BasicAuth(); !found || user != tc.user || pass != tc.pass {
|
||||
t.Errorf("%s: unexpected authorization header: %#v", n, rt.Request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserAgentRoundTripper(t *testing.T) {
|
||||
rt := &testRoundTripper{}
|
||||
req := &http.Request{
|
||||
Header: make(http.Header),
|
||||
}
|
||||
req.Header.Set("User-Agent", "other")
|
||||
NewUserAgentRoundTripper("test", rt).RoundTrip(req)
|
||||
if rt.Request == nil {
|
||||
t.Fatalf("unexpected nil request: %v", rt)
|
||||
}
|
||||
if rt.Request != req {
|
||||
t.Fatalf("round tripper should not have copied request object: %#v", rt.Request)
|
||||
}
|
||||
if rt.Request.Header.Get("User-Agent") != "other" {
|
||||
t.Errorf("unexpected user agent header: %#v", rt.Request)
|
||||
}
|
||||
|
||||
req = &http.Request{}
|
||||
NewUserAgentRoundTripper("test", rt).RoundTrip(req)
|
||||
if rt.Request == nil {
|
||||
t.Fatalf("unexpected nil request: %v", rt)
|
||||
}
|
||||
if rt.Request == req {
|
||||
t.Fatalf("round tripper should have copied request object: %#v", rt.Request)
|
||||
}
|
||||
if rt.Request.Header.Get("User-Agent") != "test" {
|
||||
t.Errorf("unexpected user agent header: %#v", rt.Request)
|
||||
}
|
||||
}
|
||||
138
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/transport.go
generated
vendored
Normal file
138
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/transport.go
generated
vendored
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 transport
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// New returns an http.RoundTripper that will provide the authentication
|
||||
// or transport level security defined by the provided Config.
|
||||
func New(config *Config) (http.RoundTripper, error) {
|
||||
// Set transport level security
|
||||
if config.Transport != nil && (config.HasCA() || config.HasCertAuth() || config.TLS.Insecure) {
|
||||
return nil, fmt.Errorf("using a custom transport with TLS certificate options or the insecure flag is not allowed")
|
||||
}
|
||||
|
||||
var (
|
||||
rt http.RoundTripper
|
||||
err error
|
||||
)
|
||||
|
||||
if config.Transport != nil {
|
||||
rt = config.Transport
|
||||
} else {
|
||||
rt, err = tlsCache.get(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return HTTPWrappersForConfig(config, rt)
|
||||
}
|
||||
|
||||
// TLSConfigFor returns a tls.Config that will provide the transport level security defined
|
||||
// by the provided Config. Will return nil if no transport level security is requested.
|
||||
func TLSConfigFor(c *Config) (*tls.Config, error) {
|
||||
if !(c.HasCA() || c.HasCertAuth() || c.TLS.Insecure) {
|
||||
return nil, nil
|
||||
}
|
||||
if c.HasCA() && c.TLS.Insecure {
|
||||
return nil, fmt.Errorf("specifying a root certificates file with the insecure flag is not allowed")
|
||||
}
|
||||
if err := loadTLSFiles(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
// Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability)
|
||||
MinVersion: tls.VersionTLS10,
|
||||
InsecureSkipVerify: c.TLS.Insecure,
|
||||
}
|
||||
|
||||
if c.HasCA() {
|
||||
tlsConfig.RootCAs = rootCertPool(c.TLS.CAData)
|
||||
}
|
||||
|
||||
if c.HasCertAuth() {
|
||||
cert, err := tls.X509KeyPair(c.TLS.CertData, c.TLS.KeyData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// loadTLSFiles copies the data from the CertFile, KeyFile, and CAFile fields into the CertData,
|
||||
// KeyData, and CAFile fields, or returns an error. If no error is returned, all three fields are
|
||||
// either populated or were empty to start.
|
||||
func loadTLSFiles(c *Config) error {
|
||||
var err error
|
||||
c.TLS.CAData, err = dataFromSliceOrFile(c.TLS.CAData, c.TLS.CAFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.TLS.CertData, err = dataFromSliceOrFile(c.TLS.CertData, c.TLS.CertFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.TLS.KeyData, err = dataFromSliceOrFile(c.TLS.KeyData, c.TLS.KeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// dataFromSliceOrFile returns data from the slice (if non-empty), or from the file,
|
||||
// or an error if an error occurred reading the file
|
||||
func dataFromSliceOrFile(data []byte, file string) ([]byte, error) {
|
||||
if len(data) > 0 {
|
||||
return data, nil
|
||||
}
|
||||
if len(file) > 0 {
|
||||
fileData, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return fileData, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// rootCertPool returns nil if caData is empty. When passed along, this will mean "use system CAs".
|
||||
// When caData is not empty, it will be the ONLY information used in the CertPool.
|
||||
func rootCertPool(caData []byte) *x509.CertPool {
|
||||
// What we really want is a copy of x509.systemRootsPool, but that isn't exposed. It's difficult to build (see the go
|
||||
// code for a look at the platform specific insanity), so we'll use the fact that RootCAs == nil gives us the system values
|
||||
// It doesn't allow trusting either/or, but hopefully that won't be an issue
|
||||
if len(caData) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if we have caData, use it
|
||||
certPool := x509.NewCertPool()
|
||||
certPool.AppendCertsFromPEM(caData)
|
||||
return certPool
|
||||
}
|
||||
204
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/transport_test.go
generated
vendored
Normal file
204
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/transport/transport_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 transport
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
rootCACert = `-----BEGIN CERTIFICATE-----
|
||||
MIIC4DCCAcqgAwIBAgIBATALBgkqhkiG9w0BAQswIzEhMB8GA1UEAwwYMTAuMTMu
|
||||
MTI5LjEwNkAxNDIxMzU5MDU4MB4XDTE1MDExNTIxNTczN1oXDTE2MDExNTIxNTcz
|
||||
OFowIzEhMB8GA1UEAwwYMTAuMTMuMTI5LjEwNkAxNDIxMzU5MDU4MIIBIjANBgkq
|
||||
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunDRXGwsiYWGFDlWH6kjGun+PshDGeZX
|
||||
xtx9lUnL8pIRWH3wX6f13PO9sktaOWW0T0mlo6k2bMlSLlSZgG9H6og0W6gLS3vq
|
||||
s4VavZ6DbXIwemZG2vbRwsvR+t4G6Nbwelm6F8RFnA1Fwt428pavmNQ/wgYzo+T1
|
||||
1eS+HiN4ACnSoDSx3QRWcgBkB1g6VReofVjx63i0J+w8Q/41L9GUuLqquFxu6ZnH
|
||||
60vTB55lHgFiDLjA1FkEz2dGvGh/wtnFlRvjaPC54JH2K1mPYAUXTreoeJtLJKX0
|
||||
ycoiyB24+zGCniUmgIsmQWRPaOPircexCp1BOeze82BT1LCZNTVaxQIDAQABoyMw
|
||||
ITAOBgNVHQ8BAf8EBAMCAKQwDwYDVR0TAQH/BAUwAwEB/zALBgkqhkiG9w0BAQsD
|
||||
ggEBADMxsUuAFlsYDpF4fRCzXXwrhbtj4oQwcHpbu+rnOPHCZupiafzZpDu+rw4x
|
||||
YGPnCb594bRTQn4pAu3Ac18NbLD5pV3uioAkv8oPkgr8aUhXqiv7KdDiaWm6sbAL
|
||||
EHiXVBBAFvQws10HMqMoKtO8f1XDNAUkWduakR/U6yMgvOPwS7xl0eUTqyRB6zGb
|
||||
K55q2dejiFWaFqB/y78txzvz6UlOZKE44g2JAVoJVM6kGaxh33q8/FmrL4kuN3ut
|
||||
W+MmJCVDvd4eEqPwbp7146ZWTqpIJ8lvA6wuChtqV8lhAPka2hD/LMqY8iXNmfXD
|
||||
uml0obOEy+ON91k+SWTJ3ggmF/U=
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
certData = `-----BEGIN CERTIFICATE-----
|
||||
MIIC6jCCAdSgAwIBAgIBCzALBgkqhkiG9w0BAQswIzEhMB8GA1UEAwwYMTAuMTMu
|
||||
MTI5LjEwNkAxNDIxMzU5MDU4MB4XDTE1MDExNTIyMDEzMVoXDTE2MDExNTIyMDEz
|
||||
MlowGzEZMBcGA1UEAxMQb3BlbnNoaWZ0LWNsaWVudDCCASIwDQYJKoZIhvcNAQEB
|
||||
BQADggEPADCCAQoCggEBAKtdhz0+uCLXw5cSYns9rU/XifFSpb/x24WDdrm72S/v
|
||||
b9BPYsAStiP148buylr1SOuNi8sTAZmlVDDIpIVwMLff+o2rKYDicn9fjbrTxTOj
|
||||
lI4pHJBH+JU3AJ0tbajupioh70jwFS0oYpwtneg2zcnE2Z4l6mhrj2okrc5Q1/X2
|
||||
I2HChtIU4JYTisObtin10QKJX01CLfYXJLa8upWzKZ4/GOcHG+eAV3jXWoXidtjb
|
||||
1Usw70amoTZ6mIVCkiu1QwCoa8+ycojGfZhvqMsAp1536ZcCul+Na+AbCv4zKS7F
|
||||
kQQaImVrXdUiFansIoofGlw/JNuoKK6ssVpS5Ic3pgcCAwEAAaM1MDMwDgYDVR0P
|
||||
AQH/BAQDAgCgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwCwYJ
|
||||
KoZIhvcNAQELA4IBAQCKLREH7bXtXtZ+8vI6cjD7W3QikiArGqbl36bAhhWsJLp/
|
||||
p/ndKz39iFNaiZ3GlwIURWOOKx3y3GA0x9m8FR+Llthf0EQ8sUjnwaknWs0Y6DQ3
|
||||
jjPFZOpV3KPCFrdMJ3++E3MgwFC/Ih/N2ebFX9EcV9Vcc6oVWMdwT0fsrhu683rq
|
||||
6GSR/3iVX1G/pmOiuaR0fNUaCyCfYrnI4zHBDgSfnlm3vIvN2lrsR/DQBakNL8DJ
|
||||
HBgKxMGeUPoneBv+c8DMXIL0EhaFXRlBv9QW45/GiAIOuyFJ0i6hCtGZpJjq4OpQ
|
||||
BRjCI+izPzFTjsxD4aORE+WOkyWFCGPWKfNejfw0
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
keyData = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAq12HPT64ItfDlxJiez2tT9eJ8VKlv/HbhYN2ubvZL+9v0E9i
|
||||
wBK2I/Xjxu7KWvVI642LyxMBmaVUMMikhXAwt9/6jaspgOJyf1+NutPFM6OUjikc
|
||||
kEf4lTcAnS1tqO6mKiHvSPAVLShinC2d6DbNycTZniXqaGuPaiStzlDX9fYjYcKG
|
||||
0hTglhOKw5u2KfXRAolfTUIt9hcktry6lbMpnj8Y5wcb54BXeNdaheJ22NvVSzDv
|
||||
RqahNnqYhUKSK7VDAKhrz7JyiMZ9mG+oywCnXnfplwK6X41r4BsK/jMpLsWRBBoi
|
||||
ZWtd1SIVqewiih8aXD8k26gorqyxWlLkhzemBwIDAQABAoIBAD2XYRs3JrGHQUpU
|
||||
FkdbVKZkvrSY0vAZOqBTLuH0zUv4UATb8487anGkWBjRDLQCgxH+jucPTrztekQK
|
||||
aW94clo0S3aNtV4YhbSYIHWs1a0It0UdK6ID7CmdWkAj6s0T8W8lQT7C46mWYVLm
|
||||
5mFnCTHi6aB42jZrqmEpC7sivWwuU0xqj3Ml8kkxQCGmyc9JjmCB4OrFFC8NNt6M
|
||||
ObvQkUI6Z3nO4phTbpxkE1/9dT0MmPIF7GhHVzJMS+EyyRYUDllZ0wvVSOM3qZT0
|
||||
JMUaBerkNwm9foKJ1+dv2nMKZZbJajv7suUDCfU44mVeaEO+4kmTKSGCGjjTBGkr
|
||||
7L1ySDECgYEA5ElIMhpdBzIivCuBIH8LlUeuzd93pqssO1G2Xg0jHtfM4tz7fyeI
|
||||
cr90dc8gpli24dkSxzLeg3Tn3wIj/Bu64m2TpZPZEIlukYvgdgArmRIPQVxerYey
|
||||
OkrfTNkxU1HXsYjLCdGcGXs5lmb+K/kuTcFxaMOs7jZi7La+jEONwf8CgYEAwCs/
|
||||
rUOOA0klDsWWisbivOiNPII79c9McZCNBqncCBfMUoiGe8uWDEO4TFHN60vFuVk9
|
||||
8PkwpCfvaBUX+ajvbafIfHxsnfk1M04WLGCeqQ/ym5Q4sQoQOcC1b1y9qc/xEWfg
|
||||
nIUuia0ukYRpl7qQa3tNg+BNFyjypW8zukUAC/kCgYB1/Kojuxx5q5/oQVPrx73k
|
||||
2bevD+B3c+DYh9MJqSCNwFtUpYIWpggPxoQan4LwdsmO0PKzocb/ilyNFj4i/vII
|
||||
NToqSc/WjDFpaDIKyuu9oWfhECye45NqLWhb/6VOuu4QA/Nsj7luMhIBehnEAHW+
|
||||
GkzTKM8oD1PxpEG3nPKXYQKBgQC6AuMPRt3XBl1NkCrpSBy/uObFlFaP2Enpf39S
|
||||
3OZ0Gv0XQrnSaL1kP8TMcz68rMrGX8DaWYsgytstR4W+jyy7WvZwsUu+GjTJ5aMG
|
||||
77uEcEBpIi9CBzivfn7hPccE8ZgqPf+n4i6q66yxBJflW5xhvafJqDtW2LcPNbW/
|
||||
bvzdmQKBgExALRUXpq+5dbmkdXBHtvXdRDZ6rVmrnjy4nI5bPw+1GqQqk6uAR6B/
|
||||
F6NmLCQOO4PDG/cuatNHIr2FrwTmGdEL6ObLUGWn9Oer9gJhHVqqsY5I4sEPo4XX
|
||||
stR0Yiw0buV6DL/moUO0HIM9Bjh96HJp+LxiIS6UCdIhMPp5HoQa
|
||||
-----END RSA PRIVATE KEY-----`
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
Config *Config
|
||||
Err bool
|
||||
TLS bool
|
||||
Default bool
|
||||
}{
|
||||
"default transport": {
|
||||
Default: true,
|
||||
Config: &Config{},
|
||||
},
|
||||
|
||||
"ca transport": {
|
||||
TLS: true,
|
||||
Config: &Config{
|
||||
TLS: TLSConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
},
|
||||
},
|
||||
},
|
||||
"bad ca file transport": {
|
||||
Err: true,
|
||||
Config: &Config{
|
||||
TLS: TLSConfig{
|
||||
CAFile: "invalid file",
|
||||
},
|
||||
},
|
||||
},
|
||||
"ca data overriding bad ca file transport": {
|
||||
TLS: true,
|
||||
Config: &Config{
|
||||
TLS: TLSConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
CAFile: "invalid file",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"cert transport": {
|
||||
TLS: true,
|
||||
Config: &Config{
|
||||
TLS: TLSConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
CertData: []byte(certData),
|
||||
KeyData: []byte(keyData),
|
||||
},
|
||||
},
|
||||
},
|
||||
"bad cert data transport": {
|
||||
Err: true,
|
||||
Config: &Config{
|
||||
TLS: TLSConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
CertData: []byte(certData),
|
||||
KeyData: []byte("bad key data"),
|
||||
},
|
||||
},
|
||||
},
|
||||
"bad file cert transport": {
|
||||
Err: true,
|
||||
Config: &Config{
|
||||
TLS: TLSConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
CertData: []byte(certData),
|
||||
KeyFile: "invalid file",
|
||||
},
|
||||
},
|
||||
},
|
||||
"key data overriding bad file cert transport": {
|
||||
TLS: true,
|
||||
Config: &Config{
|
||||
TLS: TLSConfig{
|
||||
CAData: []byte(rootCACert),
|
||||
CertData: []byte(certData),
|
||||
KeyData: []byte(keyData),
|
||||
KeyFile: "invalid file",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, testCase := range testCases {
|
||||
transport, err := New(testCase.Config)
|
||||
switch {
|
||||
case testCase.Err && err == nil:
|
||||
t.Errorf("%s: unexpected non-error", k)
|
||||
continue
|
||||
case !testCase.Err && err != nil:
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case testCase.Default && transport != http.DefaultTransport:
|
||||
t.Errorf("%s: expected the default transport, got %#v", k, transport)
|
||||
continue
|
||||
case !testCase.Default && transport == http.DefaultTransport:
|
||||
t.Errorf("%s: expected non-default transport, got %#v", k, transport)
|
||||
continue
|
||||
}
|
||||
|
||||
// We only know how to check TLSConfig on http.Transports
|
||||
if transport, ok := transport.(*http.Transport); ok {
|
||||
switch {
|
||||
case testCase.TLS && transport.TLSClientConfig == nil:
|
||||
t.Errorf("%s: expected TLSClientConfig, got %#v", k, transport)
|
||||
continue
|
||||
case !testCase.TLS && transport.TLSClientConfig != nil:
|
||||
t.Errorf("%s: expected no TLSClientConfig, got %#v", k, transport)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
126
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/componentstatus.go
generated
vendored
Normal file
126
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/componentstatus.go
generated
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ComponentStatusesGetter has a method to return a ComponentStatusInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ComponentStatusesGetter interface {
|
||||
ComponentStatuses() ComponentStatusInterface
|
||||
}
|
||||
|
||||
// ComponentStatusInterface has methods to work with ComponentStatus resources.
|
||||
type ComponentStatusInterface interface {
|
||||
Create(*api.ComponentStatus) (*api.ComponentStatus, error)
|
||||
Update(*api.ComponentStatus) (*api.ComponentStatus, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.ComponentStatus, error)
|
||||
List(opts api.ListOptions) (*api.ComponentStatusList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
ComponentStatusExpansion
|
||||
}
|
||||
|
||||
// componentStatuses implements ComponentStatusInterface
|
||||
type componentStatuses struct {
|
||||
client *CoreClient
|
||||
}
|
||||
|
||||
// newComponentStatuses returns a ComponentStatuses
|
||||
func newComponentStatuses(c *CoreClient) *componentStatuses {
|
||||
return &componentStatuses{
|
||||
client: c,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a componentStatus and creates it. Returns the server's representation of the componentStatus, and an error, if there is any.
|
||||
func (c *componentStatuses) Create(componentStatus *api.ComponentStatus) (result *api.ComponentStatus, err error) {
|
||||
result = &api.ComponentStatus{}
|
||||
err = c.client.Post().
|
||||
Resource("componentstatuses").
|
||||
Body(componentStatus).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a componentStatus and updates it. Returns the server's representation of the componentStatus, and an error, if there is any.
|
||||
func (c *componentStatuses) Update(componentStatus *api.ComponentStatus) (result *api.ComponentStatus, err error) {
|
||||
result = &api.ComponentStatus{}
|
||||
err = c.client.Put().
|
||||
Resource("componentstatuses").
|
||||
Name(componentStatus.Name).
|
||||
Body(componentStatus).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the componentStatus and deletes it. Returns an error if one occurs.
|
||||
func (c *componentStatuses) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("componentstatuses").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *componentStatuses) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("componentstatuses").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the componentStatus, and returns the corresponding componentStatus object, and an error if there is any.
|
||||
func (c *componentStatuses) Get(name string) (result *api.ComponentStatus, err error) {
|
||||
result = &api.ComponentStatus{}
|
||||
err = c.client.Get().
|
||||
Resource("componentstatuses").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ComponentStatuses that match those selectors.
|
||||
func (c *componentStatuses) List(opts api.ListOptions) (result *api.ComponentStatusList, err error) {
|
||||
result = &api.ComponentStatusList{}
|
||||
err = c.client.Get().
|
||||
Resource("componentstatuses").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested componentStatuses.
|
||||
func (c *componentStatuses) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Resource("componentstatuses").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/configmap.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/configmap.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ConfigMapsGetter has a method to return a ConfigMapInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ConfigMapsGetter interface {
|
||||
ConfigMaps(namespace string) ConfigMapInterface
|
||||
}
|
||||
|
||||
// ConfigMapInterface has methods to work with ConfigMap resources.
|
||||
type ConfigMapInterface interface {
|
||||
Create(*api.ConfigMap) (*api.ConfigMap, error)
|
||||
Update(*api.ConfigMap) (*api.ConfigMap, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.ConfigMap, error)
|
||||
List(opts api.ListOptions) (*api.ConfigMapList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
ConfigMapExpansion
|
||||
}
|
||||
|
||||
// configMaps implements ConfigMapInterface
|
||||
type configMaps struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newConfigMaps returns a ConfigMaps
|
||||
func newConfigMaps(c *CoreClient, namespace string) *configMaps {
|
||||
return &configMaps{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a configMap and creates it. Returns the server's representation of the configMap, and an error, if there is any.
|
||||
func (c *configMaps) Create(configMap *api.ConfigMap) (result *api.ConfigMap, err error) {
|
||||
result = &api.ConfigMap{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("configmaps").
|
||||
Body(configMap).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a configMap and updates it. Returns the server's representation of the configMap, and an error, if there is any.
|
||||
func (c *configMaps) Update(configMap *api.ConfigMap) (result *api.ConfigMap, err error) {
|
||||
result = &api.ConfigMap{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("configmaps").
|
||||
Name(configMap.Name).
|
||||
Body(configMap).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the configMap and deletes it. Returns an error if one occurs.
|
||||
func (c *configMaps) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("configmaps").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *configMaps) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("configmaps").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the configMap, and returns the corresponding configMap object, and an error if there is any.
|
||||
func (c *configMaps) Get(name string) (result *api.ConfigMap, err error) {
|
||||
result = &api.ConfigMap{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("configmaps").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ConfigMaps that match those selectors.
|
||||
func (c *configMaps) List(opts api.ListOptions) (result *api.ConfigMapList, err error) {
|
||||
result = &api.ConfigMapList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("configmaps").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested configMaps.
|
||||
func (c *configMaps) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("configmaps").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
165
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/core_client.go
generated
vendored
Normal file
165
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/core_client.go
generated
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
unversioned "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
type CoreInterface interface {
|
||||
ComponentStatusesGetter
|
||||
ConfigMapsGetter
|
||||
EndpointsGetter
|
||||
EventsGetter
|
||||
LimitRangesGetter
|
||||
NamespacesGetter
|
||||
NodesGetter
|
||||
PersistentVolumesGetter
|
||||
PersistentVolumeClaimsGetter
|
||||
PodsGetter
|
||||
PodTemplatesGetter
|
||||
ReplicationControllersGetter
|
||||
ResourceQuotasGetter
|
||||
SecretsGetter
|
||||
ServicesGetter
|
||||
ServiceAccountsGetter
|
||||
}
|
||||
|
||||
// CoreClient is used to interact with features provided by the Core group.
|
||||
type CoreClient struct {
|
||||
*unversioned.RESTClient
|
||||
}
|
||||
|
||||
func (c *CoreClient) ComponentStatuses() ComponentStatusInterface {
|
||||
return newComponentStatuses(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ConfigMaps(namespace string) ConfigMapInterface {
|
||||
return newConfigMaps(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Endpoints(namespace string) EndpointsInterface {
|
||||
return newEndpoints(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Events(namespace string) EventInterface {
|
||||
return newEvents(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) LimitRanges(namespace string) LimitRangeInterface {
|
||||
return newLimitRanges(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Namespaces() NamespaceInterface {
|
||||
return newNamespaces(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Nodes() NodeInterface {
|
||||
return newNodes(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) PersistentVolumes() PersistentVolumeInterface {
|
||||
return newPersistentVolumes(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) PersistentVolumeClaims(namespace string) PersistentVolumeClaimInterface {
|
||||
return newPersistentVolumeClaims(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Pods(namespace string) PodInterface {
|
||||
return newPods(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) PodTemplates(namespace string) PodTemplateInterface {
|
||||
return newPodTemplates(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ReplicationControllers(namespace string) ReplicationControllerInterface {
|
||||
return newReplicationControllers(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ResourceQuotas(namespace string) ResourceQuotaInterface {
|
||||
return newResourceQuotas(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Secrets(namespace string) SecretInterface {
|
||||
return newSecrets(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Services(namespace string) ServiceInterface {
|
||||
return newServices(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ServiceAccounts(namespace string) ServiceAccountInterface {
|
||||
return newServiceAccounts(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new CoreClient for the given config.
|
||||
func NewForConfig(c *unversioned.Config) (*CoreClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := unversioned.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &CoreClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new CoreClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *unversioned.Config) *CoreClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new CoreClient for the given RESTClient.
|
||||
func New(c *unversioned.RESTClient) *CoreClient {
|
||||
return &CoreClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *unversioned.Config) error {
|
||||
// if core group is not registered, return an error
|
||||
g, err := registered.Group("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/api"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = unversioned.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.Codec = api.Codecs.LegacyCodec(*config.GroupVersion)
|
||||
if config.QPS == 0 {
|
||||
config.QPS = 5
|
||||
}
|
||||
if config.Burst == 0 {
|
||||
config.Burst = 10
|
||||
}
|
||||
return nil
|
||||
}
|
||||
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/doc.go
generated
vendored
Normal file
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned has the automatically generated clients for unversioned resources.
|
||||
package unversioned
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/endpoints.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/endpoints.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// EndpointsGetter has a method to return a EndpointsInterface.
|
||||
// A group's client should implement this interface.
|
||||
type EndpointsGetter interface {
|
||||
Endpoints(namespace string) EndpointsInterface
|
||||
}
|
||||
|
||||
// EndpointsInterface has methods to work with Endpoints resources.
|
||||
type EndpointsInterface interface {
|
||||
Create(*api.Endpoints) (*api.Endpoints, error)
|
||||
Update(*api.Endpoints) (*api.Endpoints, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Endpoints, error)
|
||||
List(opts api.ListOptions) (*api.EndpointsList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
EndpointsExpansion
|
||||
}
|
||||
|
||||
// endpoints implements EndpointsInterface
|
||||
type endpoints struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newEndpoints returns a Endpoints
|
||||
func newEndpoints(c *CoreClient, namespace string) *endpoints {
|
||||
return &endpoints{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a endpoints and creates it. Returns the server's representation of the endpoints, and an error, if there is any.
|
||||
func (c *endpoints) Create(endpoints *api.Endpoints) (result *api.Endpoints, err error) {
|
||||
result = &api.Endpoints{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("endpoints").
|
||||
Body(endpoints).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a endpoints and updates it. Returns the server's representation of the endpoints, and an error, if there is any.
|
||||
func (c *endpoints) Update(endpoints *api.Endpoints) (result *api.Endpoints, err error) {
|
||||
result = &api.Endpoints{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("endpoints").
|
||||
Name(endpoints.Name).
|
||||
Body(endpoints).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the endpoints and deletes it. Returns an error if one occurs.
|
||||
func (c *endpoints) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("endpoints").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *endpoints) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("endpoints").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the endpoints, and returns the corresponding endpoints object, and an error if there is any.
|
||||
func (c *endpoints) Get(name string) (result *api.Endpoints, err error) {
|
||||
result = &api.Endpoints{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("endpoints").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Endpoints that match those selectors.
|
||||
func (c *endpoints) List(opts api.ListOptions) (result *api.EndpointsList, err error) {
|
||||
result = &api.EndpointsList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("endpoints").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested endpoints.
|
||||
func (c *endpoints) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("endpoints").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/event.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/event.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// EventsGetter has a method to return a EventInterface.
|
||||
// A group's client should implement this interface.
|
||||
type EventsGetter interface {
|
||||
Events(namespace string) EventInterface
|
||||
}
|
||||
|
||||
// EventInterface has methods to work with Event resources.
|
||||
type EventInterface interface {
|
||||
Create(*api.Event) (*api.Event, error)
|
||||
Update(*api.Event) (*api.Event, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Event, error)
|
||||
List(opts api.ListOptions) (*api.EventList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
EventExpansion
|
||||
}
|
||||
|
||||
// events implements EventInterface
|
||||
type events struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newEvents returns a Events
|
||||
func newEvents(c *CoreClient, namespace string) *events {
|
||||
return &events{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a event and creates it. Returns the server's representation of the event, and an error, if there is any.
|
||||
func (c *events) Create(event *api.Event) (result *api.Event, err error) {
|
||||
result = &api.Event{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("events").
|
||||
Body(event).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a event and updates it. Returns the server's representation of the event, and an error, if there is any.
|
||||
func (c *events) Update(event *api.Event) (result *api.Event, err error) {
|
||||
result = &api.Event{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("events").
|
||||
Name(event.Name).
|
||||
Body(event).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the event and deletes it. Returns an error if one occurs.
|
||||
func (c *events) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("events").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *events) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("events").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the event, and returns the corresponding event object, and an error if there is any.
|
||||
func (c *events) Get(name string) (result *api.Event, err error) {
|
||||
result = &api.Event{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("events").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Events that match those selectors.
|
||||
func (c *events) List(opts api.ListOptions) (result *api.EventList, err error) {
|
||||
result = &api.EventList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("events").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested events.
|
||||
func (c *events) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("events").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
157
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/event_expansion.go
generated
vendored
Normal file
157
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/event_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// The EventExpansion interface allows manually adding extra methods to the EventInterface.
|
||||
type EventExpansion interface {
|
||||
// CreateWithEventNamespace is the same as a Create, except that it sends the request to the event.Namespace.
|
||||
CreateWithEventNamespace(event *api.Event) (*api.Event, error)
|
||||
// UpdateWithEventNamespace is the same as a Update, except that it sends the request to the event.Namespace.
|
||||
UpdateWithEventNamespace(event *api.Event) (*api.Event, error)
|
||||
Patch(event *api.Event, data []byte) (*api.Event, error)
|
||||
// Search finds events about the specified object
|
||||
Search(objOrRef runtime.Object) (*api.EventList, error)
|
||||
// Returns the appropriate field selector based on the API version being used to communicate with the server.
|
||||
// The returned field selector can be used with List and Watch to filter desired events.
|
||||
GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector
|
||||
}
|
||||
|
||||
// CreateWithEventNamespace makes a new event. Returns the copy of the event the server returns,
|
||||
// or an error. The namespace to create the event within is deduced from the
|
||||
// event; it must either match this event client's namespace, or this event
|
||||
// client must have been created with the "" namespace.
|
||||
func (e *events) CreateWithEventNamespace(event *api.Event) (*api.Event, error) {
|
||||
if e.ns != "" && event.Namespace != e.ns {
|
||||
return nil, fmt.Errorf("can't create an event with namespace '%v' in namespace '%v'", event.Namespace, e.ns)
|
||||
}
|
||||
result := &api.Event{}
|
||||
err := e.client.Post().
|
||||
NamespaceIfScoped(event.Namespace, len(event.Namespace) > 0).
|
||||
Resource("events").
|
||||
Body(event).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UpdateWithEventNamespace modifies an existing event. It returns the copy of the event that the server returns,
|
||||
// or an error. The namespace and key to update the event within is deduced from the event. The
|
||||
// namespace must either match this event client's namespace, or this event client must have been
|
||||
// created with the "" namespace. Update also requires the ResourceVersion to be set in the event
|
||||
// object.
|
||||
func (e *events) UpdateWithEventNamespace(event *api.Event) (*api.Event, error) {
|
||||
result := &api.Event{}
|
||||
err := e.client.Put().
|
||||
NamespaceIfScoped(event.Namespace, len(event.Namespace) > 0).
|
||||
Resource("events").
|
||||
Name(event.Name).
|
||||
Body(event).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Patch modifies an existing event. It returns the copy of the event that the server returns, or an
|
||||
// error. The namespace and name of the target event is deduced from the incompleteEvent. The
|
||||
// namespace must either match this event client's namespace, or this event client must have been
|
||||
// created with the "" namespace.
|
||||
func (e *events) Patch(incompleteEvent *api.Event, data []byte) (*api.Event, error) {
|
||||
result := &api.Event{}
|
||||
err := e.client.Patch(api.StrategicMergePatchType).
|
||||
NamespaceIfScoped(incompleteEvent.Namespace, len(incompleteEvent.Namespace) > 0).
|
||||
Resource("events").
|
||||
Name(incompleteEvent.Name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Search finds events about the specified object. The namespace of the
|
||||
// object must match this event's client namespace unless the event client
|
||||
// was made with the "" namespace.
|
||||
func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) {
|
||||
ref, err := api.GetReference(objOrRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if e.ns != "" && ref.Namespace != e.ns {
|
||||
return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.ns)
|
||||
}
|
||||
stringRefKind := string(ref.Kind)
|
||||
var refKind *string
|
||||
if stringRefKind != "" {
|
||||
refKind = &stringRefKind
|
||||
}
|
||||
stringRefUID := string(ref.UID)
|
||||
var refUID *string
|
||||
if stringRefUID != "" {
|
||||
refUID = &stringRefUID
|
||||
}
|
||||
fieldSelector := e.GetFieldSelector(&ref.Name, &ref.Namespace, refKind, refUID)
|
||||
return e.List(api.ListOptions{FieldSelector: fieldSelector})
|
||||
}
|
||||
|
||||
// Returns the appropriate field selector based on the API version being used to communicate with the server.
|
||||
// The returned field selector can be used with List and Watch to filter desired events.
|
||||
func (e *events) GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector {
|
||||
apiVersion := e.client.APIVersion().String()
|
||||
field := fields.Set{}
|
||||
if involvedObjectName != nil {
|
||||
field[GetInvolvedObjectNameFieldLabel(apiVersion)] = *involvedObjectName
|
||||
}
|
||||
if involvedObjectNamespace != nil {
|
||||
field["involvedObject.namespace"] = *involvedObjectNamespace
|
||||
}
|
||||
if involvedObjectKind != nil {
|
||||
field["involvedObject.kind"] = *involvedObjectKind
|
||||
}
|
||||
if involvedObjectUID != nil {
|
||||
field["involvedObject.uid"] = *involvedObjectUID
|
||||
}
|
||||
return field.AsSelector()
|
||||
}
|
||||
|
||||
// Returns the appropriate field label to use for name of the involved object as per the given API version.
|
||||
func GetInvolvedObjectNameFieldLabel(version string) string {
|
||||
return "involvedObject.name"
|
||||
}
|
||||
|
||||
// TODO: This is a temporary arrangement and will be removed once all clients are moved to use the clientset.
|
||||
type EventSinkImpl struct {
|
||||
Interface EventInterface
|
||||
}
|
||||
|
||||
func (e *EventSinkImpl) Create(event *api.Event) (*api.Event, error) {
|
||||
return e.Interface.CreateWithEventNamespace(event)
|
||||
}
|
||||
|
||||
func (e *EventSinkImpl) Update(event *api.Event) (*api.Event, error) {
|
||||
return e.Interface.UpdateWithEventNamespace(event)
|
||||
}
|
||||
|
||||
func (e *EventSinkImpl) Patch(event *api.Event, data []byte) (*api.Event, error) {
|
||||
return e.Interface.Patch(event, data)
|
||||
}
|
||||
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/doc.go
generated
vendored
Normal file
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake has the automatically generated clients.
|
||||
package fake
|
||||
95
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_componentstatus.go
generated
vendored
Normal file
95
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_componentstatus.go
generated
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeComponentStatuses implements ComponentStatusInterface
|
||||
type FakeComponentStatuses struct {
|
||||
Fake *FakeCore
|
||||
}
|
||||
|
||||
func (c *FakeComponentStatuses) Create(componentStatus *api.ComponentStatus) (result *api.ComponentStatus, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootCreateAction("componentstatuses", componentStatus), &api.ComponentStatus{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ComponentStatus), err
|
||||
}
|
||||
|
||||
func (c *FakeComponentStatuses) Update(componentStatus *api.ComponentStatus) (result *api.ComponentStatus, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootUpdateAction("componentstatuses", componentStatus), &api.ComponentStatus{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ComponentStatus), err
|
||||
}
|
||||
|
||||
func (c *FakeComponentStatuses) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewRootDeleteAction("componentstatuses", name), &api.ComponentStatus{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeComponentStatuses) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewRootDeleteCollectionAction("componentstatuses", listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.ComponentStatusList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeComponentStatuses) Get(name string) (result *api.ComponentStatus, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootGetAction("componentstatuses", name), &api.ComponentStatus{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ComponentStatus), err
|
||||
}
|
||||
|
||||
func (c *FakeComponentStatuses) List(opts api.ListOptions) (result *api.ComponentStatusList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootListAction("componentstatuses", opts), &api.ComponentStatusList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.ComponentStatusList{}
|
||||
for _, item := range obj.(*api.ComponentStatusList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested componentStatuses.
|
||||
func (c *FakeComponentStatuses) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewRootWatchAction("componentstatuses", opts))
|
||||
}
|
||||
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_configmap.go
generated
vendored
Normal file
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_configmap.go
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeConfigMaps implements ConfigMapInterface
|
||||
type FakeConfigMaps struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeConfigMaps) Create(configMap *api.ConfigMap) (result *api.ConfigMap, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("configmaps", c.ns, configMap), &api.ConfigMap{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ConfigMap), err
|
||||
}
|
||||
|
||||
func (c *FakeConfigMaps) Update(configMap *api.ConfigMap) (result *api.ConfigMap, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("configmaps", c.ns, configMap), &api.ConfigMap{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ConfigMap), err
|
||||
}
|
||||
|
||||
func (c *FakeConfigMaps) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("configmaps", c.ns, name), &api.ConfigMap{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeConfigMaps) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("configmaps", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.ConfigMapList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeConfigMaps) Get(name string) (result *api.ConfigMap, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("configmaps", c.ns, name), &api.ConfigMap{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ConfigMap), err
|
||||
}
|
||||
|
||||
func (c *FakeConfigMaps) List(opts api.ListOptions) (result *api.ConfigMapList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("configmaps", c.ns, opts), &api.ConfigMapList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.ConfigMapList{}
|
||||
for _, item := range obj.(*api.ConfigMapList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested configMaps.
|
||||
func (c *FakeConfigMaps) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("configmaps", c.ns, opts))
|
||||
|
||||
}
|
||||
90
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_core_client.go
generated
vendored
Normal file
90
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_core_client.go
generated
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
unversioned "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned"
|
||||
)
|
||||
|
||||
type FakeCore struct {
|
||||
*core.Fake
|
||||
}
|
||||
|
||||
func (c *FakeCore) ComponentStatuses() unversioned.ComponentStatusInterface {
|
||||
return &FakeComponentStatuses{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ConfigMaps(namespace string) unversioned.ConfigMapInterface {
|
||||
return &FakeConfigMaps{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Endpoints(namespace string) unversioned.EndpointsInterface {
|
||||
return &FakeEndpoints{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Events(namespace string) unversioned.EventInterface {
|
||||
return &FakeEvents{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) LimitRanges(namespace string) unversioned.LimitRangeInterface {
|
||||
return &FakeLimitRanges{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Namespaces() unversioned.NamespaceInterface {
|
||||
return &FakeNamespaces{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Nodes() unversioned.NodeInterface {
|
||||
return &FakeNodes{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) PersistentVolumes() unversioned.PersistentVolumeInterface {
|
||||
return &FakePersistentVolumes{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) PersistentVolumeClaims(namespace string) unversioned.PersistentVolumeClaimInterface {
|
||||
return &FakePersistentVolumeClaims{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Pods(namespace string) unversioned.PodInterface {
|
||||
return &FakePods{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) PodTemplates(namespace string) unversioned.PodTemplateInterface {
|
||||
return &FakePodTemplates{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ReplicationControllers(namespace string) unversioned.ReplicationControllerInterface {
|
||||
return &FakeReplicationControllers{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ResourceQuotas(namespace string) unversioned.ResourceQuotaInterface {
|
||||
return &FakeResourceQuotas{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Secrets(namespace string) unversioned.SecretInterface {
|
||||
return &FakeSecrets{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Services(namespace string) unversioned.ServiceInterface {
|
||||
return &FakeServices{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ServiceAccounts(namespace string) unversioned.ServiceAccountInterface {
|
||||
return &FakeServiceAccounts{c, namespace}
|
||||
}
|
||||
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_endpoints.go
generated
vendored
Normal file
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_endpoints.go
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeEndpoints implements EndpointsInterface
|
||||
type FakeEndpoints struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeEndpoints) Create(endpoints *api.Endpoints) (result *api.Endpoints, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("endpoints", c.ns, endpoints), &api.Endpoints{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Endpoints), err
|
||||
}
|
||||
|
||||
func (c *FakeEndpoints) Update(endpoints *api.Endpoints) (result *api.Endpoints, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("endpoints", c.ns, endpoints), &api.Endpoints{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Endpoints), err
|
||||
}
|
||||
|
||||
func (c *FakeEndpoints) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("endpoints", c.ns, name), &api.Endpoints{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeEndpoints) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("endpoints", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.EndpointsList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeEndpoints) Get(name string) (result *api.Endpoints, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("endpoints", c.ns, name), &api.Endpoints{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Endpoints), err
|
||||
}
|
||||
|
||||
func (c *FakeEndpoints) List(opts api.ListOptions) (result *api.EndpointsList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("endpoints", c.ns, opts), &api.EndpointsList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.EndpointsList{}
|
||||
for _, item := range obj.(*api.EndpointsList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested endpoints.
|
||||
func (c *FakeEndpoints) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("endpoints", c.ns, opts))
|
||||
|
||||
}
|
||||
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_event.go
generated
vendored
Normal file
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_event.go
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeEvents implements EventInterface
|
||||
type FakeEvents struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeEvents) Create(event *api.Event) (result *api.Event, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("events", c.ns, event), &api.Event{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Event), err
|
||||
}
|
||||
|
||||
func (c *FakeEvents) Update(event *api.Event) (result *api.Event, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("events", c.ns, event), &api.Event{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Event), err
|
||||
}
|
||||
|
||||
func (c *FakeEvents) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("events", c.ns, name), &api.Event{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeEvents) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("events", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.EventList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeEvents) Get(name string) (result *api.Event, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("events", c.ns, name), &api.Event{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Event), err
|
||||
}
|
||||
|
||||
func (c *FakeEvents) List(opts api.ListOptions) (result *api.EventList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("events", c.ns, opts), &api.EventList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.EventList{}
|
||||
for _, item := range obj.(*api.EventList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested events.
|
||||
func (c *FakeEvents) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("events", c.ns, opts))
|
||||
|
||||
}
|
||||
88
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_event_expansion.go
generated
vendored
Normal file
88
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_event_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/testing/core"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func (c *FakeEvents) CreateWithEventNamespace(event *api.Event) (*api.Event, error) {
|
||||
action := core.NewRootCreateAction("events", event)
|
||||
if c.ns != "" {
|
||||
action = core.NewCreateAction("events", c.ns, event)
|
||||
}
|
||||
obj, err := c.Fake.Invokes(action, event)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*api.Event), err
|
||||
}
|
||||
|
||||
// Update replaces an existing event. Returns the copy of the event the server returns, or an error.
|
||||
func (c *FakeEvents) UpdateWithEventNamespace(event *api.Event) (*api.Event, error) {
|
||||
action := core.NewRootUpdateAction("events", event)
|
||||
if c.ns != "" {
|
||||
action = core.NewUpdateAction("events", c.ns, event)
|
||||
}
|
||||
obj, err := c.Fake.Invokes(action, event)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*api.Event), err
|
||||
}
|
||||
|
||||
// Patch patches an existing event. Returns the copy of the event the server returns, or an error.
|
||||
func (c *FakeEvents) Patch(event *api.Event, data []byte) (*api.Event, error) {
|
||||
action := core.NewRootPatchAction("events", event)
|
||||
if c.ns != "" {
|
||||
action = core.NewPatchAction("events", c.ns, event)
|
||||
}
|
||||
obj, err := c.Fake.Invokes(action, event)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*api.Event), err
|
||||
}
|
||||
|
||||
// Search returns a list of events matching the specified object.
|
||||
func (c *FakeEvents) Search(objOrRef runtime.Object) (*api.EventList, error) {
|
||||
action := core.NewRootListAction("events", api.ListOptions{})
|
||||
if c.ns != "" {
|
||||
action = core.NewListAction("events", c.ns, api.ListOptions{})
|
||||
}
|
||||
obj, err := c.Fake.Invokes(action, &api.EventList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*api.EventList), err
|
||||
}
|
||||
|
||||
func (c *FakeEvents) GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector {
|
||||
action := core.GenericActionImpl{}
|
||||
action.Verb = "get-field-selector"
|
||||
action.Resource = "events"
|
||||
|
||||
c.Fake.Invokes(action, nil)
|
||||
return fields.Everything()
|
||||
}
|
||||
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_limitrange.go
generated
vendored
Normal file
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_limitrange.go
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeLimitRanges implements LimitRangeInterface
|
||||
type FakeLimitRanges struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeLimitRanges) Create(limitRange *api.LimitRange) (result *api.LimitRange, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("limitranges", c.ns, limitRange), &api.LimitRange{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.LimitRange), err
|
||||
}
|
||||
|
||||
func (c *FakeLimitRanges) Update(limitRange *api.LimitRange) (result *api.LimitRange, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("limitranges", c.ns, limitRange), &api.LimitRange{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.LimitRange), err
|
||||
}
|
||||
|
||||
func (c *FakeLimitRanges) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("limitranges", c.ns, name), &api.LimitRange{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeLimitRanges) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("limitranges", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.LimitRangeList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeLimitRanges) Get(name string) (result *api.LimitRange, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("limitranges", c.ns, name), &api.LimitRange{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.LimitRange), err
|
||||
}
|
||||
|
||||
func (c *FakeLimitRanges) List(opts api.ListOptions) (result *api.LimitRangeList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("limitranges", c.ns, opts), &api.LimitRangeList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.LimitRangeList{}
|
||||
for _, item := range obj.(*api.LimitRangeList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested limitRanges.
|
||||
func (c *FakeLimitRanges) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("limitranges", c.ns, opts))
|
||||
|
||||
}
|
||||
104
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_namespace.go
generated
vendored
Normal file
104
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_namespace.go
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeNamespaces implements NamespaceInterface
|
||||
type FakeNamespaces struct {
|
||||
Fake *FakeCore
|
||||
}
|
||||
|
||||
func (c *FakeNamespaces) Create(namespace *api.Namespace) (result *api.Namespace, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootCreateAction("namespaces", namespace), &api.Namespace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Namespace), err
|
||||
}
|
||||
|
||||
func (c *FakeNamespaces) Update(namespace *api.Namespace) (result *api.Namespace, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootUpdateAction("namespaces", namespace), &api.Namespace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Namespace), err
|
||||
}
|
||||
|
||||
func (c *FakeNamespaces) UpdateStatus(namespace *api.Namespace) (*api.Namespace, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootUpdateSubresourceAction("namespaces", "status", namespace), &api.Namespace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Namespace), err
|
||||
}
|
||||
|
||||
func (c *FakeNamespaces) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewRootDeleteAction("namespaces", name), &api.Namespace{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeNamespaces) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewRootDeleteCollectionAction("namespaces", listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.NamespaceList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeNamespaces) Get(name string) (result *api.Namespace, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootGetAction("namespaces", name), &api.Namespace{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Namespace), err
|
||||
}
|
||||
|
||||
func (c *FakeNamespaces) List(opts api.ListOptions) (result *api.NamespaceList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootListAction("namespaces", opts), &api.NamespaceList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.NamespaceList{}
|
||||
for _, item := range obj.(*api.NamespaceList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested namespaces.
|
||||
func (c *FakeNamespaces) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewRootWatchAction("namespaces", opts))
|
||||
}
|
||||
37
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_namespace_expansion.go
generated
vendored
Normal file
37
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_namespace_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/testing/core"
|
||||
)
|
||||
|
||||
func (c *FakeNamespaces) Finalize(namespace *api.Namespace) (*api.Namespace, error) {
|
||||
action := core.CreateActionImpl{}
|
||||
action.Verb = "create"
|
||||
action.Resource = "namespaces"
|
||||
action.Subresource = "finalize"
|
||||
action.Object = namespace
|
||||
|
||||
obj, err := c.Fake.Invokes(action, namespace)
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*api.Namespace), err
|
||||
}
|
||||
104
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_node.go
generated
vendored
Normal file
104
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_node.go
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeNodes implements NodeInterface
|
||||
type FakeNodes struct {
|
||||
Fake *FakeCore
|
||||
}
|
||||
|
||||
func (c *FakeNodes) Create(node *api.Node) (result *api.Node, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootCreateAction("nodes", node), &api.Node{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Node), err
|
||||
}
|
||||
|
||||
func (c *FakeNodes) Update(node *api.Node) (result *api.Node, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootUpdateAction("nodes", node), &api.Node{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Node), err
|
||||
}
|
||||
|
||||
func (c *FakeNodes) UpdateStatus(node *api.Node) (*api.Node, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootUpdateSubresourceAction("nodes", "status", node), &api.Node{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Node), err
|
||||
}
|
||||
|
||||
func (c *FakeNodes) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewRootDeleteAction("nodes", name), &api.Node{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeNodes) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewRootDeleteCollectionAction("nodes", listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.NodeList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeNodes) Get(name string) (result *api.Node, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootGetAction("nodes", name), &api.Node{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Node), err
|
||||
}
|
||||
|
||||
func (c *FakeNodes) List(opts api.ListOptions) (result *api.NodeList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootListAction("nodes", opts), &api.NodeList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.NodeList{}
|
||||
for _, item := range obj.(*api.NodeList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested nodes.
|
||||
func (c *FakeNodes) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewRootWatchAction("nodes", opts))
|
||||
}
|
||||
104
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_persistentvolume.go
generated
vendored
Normal file
104
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_persistentvolume.go
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakePersistentVolumes implements PersistentVolumeInterface
|
||||
type FakePersistentVolumes struct {
|
||||
Fake *FakeCore
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumes) Create(persistentVolume *api.PersistentVolume) (result *api.PersistentVolume, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootCreateAction("persistentvolumes", persistentVolume), &api.PersistentVolume{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolume), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumes) Update(persistentVolume *api.PersistentVolume) (result *api.PersistentVolume, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootUpdateAction("persistentvolumes", persistentVolume), &api.PersistentVolume{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolume), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumes) UpdateStatus(persistentVolume *api.PersistentVolume) (*api.PersistentVolume, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootUpdateSubresourceAction("persistentvolumes", "status", persistentVolume), &api.PersistentVolume{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolume), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumes) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewRootDeleteAction("persistentvolumes", name), &api.PersistentVolume{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumes) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewRootDeleteCollectionAction("persistentvolumes", listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.PersistentVolumeList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumes) Get(name string) (result *api.PersistentVolume, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootGetAction("persistentvolumes", name), &api.PersistentVolume{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolume), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumes) List(opts api.ListOptions) (result *api.PersistentVolumeList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewRootListAction("persistentvolumes", opts), &api.PersistentVolumeList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.PersistentVolumeList{}
|
||||
for _, item := range obj.(*api.PersistentVolumeList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested persistentVolumes.
|
||||
func (c *FakePersistentVolumes) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewRootWatchAction("persistentvolumes", opts))
|
||||
}
|
||||
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_persistentvolumeclaim.go
generated
vendored
Normal file
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_persistentvolumeclaim.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakePersistentVolumeClaims implements PersistentVolumeClaimInterface
|
||||
type FakePersistentVolumeClaims struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumeClaims) Create(persistentVolumeClaim *api.PersistentVolumeClaim) (result *api.PersistentVolumeClaim, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("persistentvolumeclaims", c.ns, persistentVolumeClaim), &api.PersistentVolumeClaim{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolumeClaim), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumeClaims) Update(persistentVolumeClaim *api.PersistentVolumeClaim) (result *api.PersistentVolumeClaim, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("persistentvolumeclaims", c.ns, persistentVolumeClaim), &api.PersistentVolumeClaim{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolumeClaim), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumeClaims) UpdateStatus(persistentVolumeClaim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("persistentvolumeclaims", "status", c.ns, persistentVolumeClaim), &api.PersistentVolumeClaim{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolumeClaim), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumeClaims) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("persistentvolumeclaims", c.ns, name), &api.PersistentVolumeClaim{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumeClaims) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("persistentvolumeclaims", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.PersistentVolumeClaimList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumeClaims) Get(name string) (result *api.PersistentVolumeClaim, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("persistentvolumeclaims", c.ns, name), &api.PersistentVolumeClaim{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PersistentVolumeClaim), err
|
||||
}
|
||||
|
||||
func (c *FakePersistentVolumeClaims) List(opts api.ListOptions) (result *api.PersistentVolumeClaimList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("persistentvolumeclaims", c.ns, opts), &api.PersistentVolumeClaimList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.PersistentVolumeClaimList{}
|
||||
for _, item := range obj.(*api.PersistentVolumeClaimList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested persistentVolumeClaims.
|
||||
func (c *FakePersistentVolumeClaims) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("persistentvolumeclaims", c.ns, opts))
|
||||
|
||||
}
|
||||
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_pod.go
generated
vendored
Normal file
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_pod.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakePods implements PodInterface
|
||||
type FakePods struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakePods) Create(pod *api.Pod) (result *api.Pod, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("pods", c.ns, pod), &api.Pod{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Pod), err
|
||||
}
|
||||
|
||||
func (c *FakePods) Update(pod *api.Pod) (result *api.Pod, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("pods", c.ns, pod), &api.Pod{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Pod), err
|
||||
}
|
||||
|
||||
func (c *FakePods) UpdateStatus(pod *api.Pod) (*api.Pod, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("pods", "status", c.ns, pod), &api.Pod{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Pod), err
|
||||
}
|
||||
|
||||
func (c *FakePods) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("pods", c.ns, name), &api.Pod{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePods) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("pods", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.PodList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePods) Get(name string) (result *api.Pod, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("pods", c.ns, name), &api.Pod{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Pod), err
|
||||
}
|
||||
|
||||
func (c *FakePods) List(opts api.ListOptions) (result *api.PodList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("pods", c.ns, opts), &api.PodList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.PodList{}
|
||||
for _, item := range obj.(*api.PodList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested pods.
|
||||
func (c *FakePods) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("pods", c.ns, opts))
|
||||
|
||||
}
|
||||
46
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_pod_expansion.go
generated
vendored
Normal file
46
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_pod_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/testing/core"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
func (c *FakePods) Bind(binding *api.Binding) error {
|
||||
action := core.CreateActionImpl{}
|
||||
action.Verb = "create"
|
||||
action.Resource = "pods"
|
||||
action.Subresource = "bindings"
|
||||
action.Object = binding
|
||||
|
||||
_, err := c.Fake.Invokes(action, binding)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePods) GetLogs(name string, opts *api.PodLogOptions) *client.Request {
|
||||
action := core.GenericActionImpl{}
|
||||
action.Verb = "get"
|
||||
action.Namespace = c.ns
|
||||
action.Resource = "pod"
|
||||
action.Subresource = "logs"
|
||||
action.Value = opts
|
||||
|
||||
_, _ = c.Fake.Invokes(action, &api.Pod{})
|
||||
return &client.Request{}
|
||||
}
|
||||
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_podtemplate.go
generated
vendored
Normal file
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_podtemplate.go
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakePodTemplates implements PodTemplateInterface
|
||||
type FakePodTemplates struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakePodTemplates) Create(podTemplate *api.PodTemplate) (result *api.PodTemplate, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("podtemplates", c.ns, podTemplate), &api.PodTemplate{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PodTemplate), err
|
||||
}
|
||||
|
||||
func (c *FakePodTemplates) Update(podTemplate *api.PodTemplate) (result *api.PodTemplate, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("podtemplates", c.ns, podTemplate), &api.PodTemplate{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PodTemplate), err
|
||||
}
|
||||
|
||||
func (c *FakePodTemplates) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("podtemplates", c.ns, name), &api.PodTemplate{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePodTemplates) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("podtemplates", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.PodTemplateList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePodTemplates) Get(name string) (result *api.PodTemplate, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("podtemplates", c.ns, name), &api.PodTemplate{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.PodTemplate), err
|
||||
}
|
||||
|
||||
func (c *FakePodTemplates) List(opts api.ListOptions) (result *api.PodTemplateList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("podtemplates", c.ns, opts), &api.PodTemplateList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.PodTemplateList{}
|
||||
for _, item := range obj.(*api.PodTemplateList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested podTemplates.
|
||||
func (c *FakePodTemplates) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("podtemplates", c.ns, opts))
|
||||
|
||||
}
|
||||
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_replicationcontroller.go
generated
vendored
Normal file
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_replicationcontroller.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeReplicationControllers implements ReplicationControllerInterface
|
||||
type FakeReplicationControllers struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeReplicationControllers) Create(replicationController *api.ReplicationController) (result *api.ReplicationController, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("replicationcontrollers", c.ns, replicationController), &api.ReplicationController{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ReplicationController), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicationControllers) Update(replicationController *api.ReplicationController) (result *api.ReplicationController, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("replicationcontrollers", c.ns, replicationController), &api.ReplicationController{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ReplicationController), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicationControllers) UpdateStatus(replicationController *api.ReplicationController) (*api.ReplicationController, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("replicationcontrollers", "status", c.ns, replicationController), &api.ReplicationController{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ReplicationController), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicationControllers) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("replicationcontrollers", c.ns, name), &api.ReplicationController{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeReplicationControllers) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("replicationcontrollers", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.ReplicationControllerList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeReplicationControllers) Get(name string) (result *api.ReplicationController, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("replicationcontrollers", c.ns, name), &api.ReplicationController{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ReplicationController), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicationControllers) List(opts api.ListOptions) (result *api.ReplicationControllerList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("replicationcontrollers", c.ns, opts), &api.ReplicationControllerList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.ReplicationControllerList{}
|
||||
for _, item := range obj.(*api.ReplicationControllerList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested replicationControllers.
|
||||
func (c *FakeReplicationControllers) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("replicationcontrollers", c.ns, opts))
|
||||
|
||||
}
|
||||
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_resourcequota.go
generated
vendored
Normal file
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_resourcequota.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeResourceQuotas implements ResourceQuotaInterface
|
||||
type FakeResourceQuotas struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeResourceQuotas) Create(resourceQuota *api.ResourceQuota) (result *api.ResourceQuota, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("resourcequotas", c.ns, resourceQuota), &api.ResourceQuota{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ResourceQuota), err
|
||||
}
|
||||
|
||||
func (c *FakeResourceQuotas) Update(resourceQuota *api.ResourceQuota) (result *api.ResourceQuota, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("resourcequotas", c.ns, resourceQuota), &api.ResourceQuota{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ResourceQuota), err
|
||||
}
|
||||
|
||||
func (c *FakeResourceQuotas) UpdateStatus(resourceQuota *api.ResourceQuota) (*api.ResourceQuota, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("resourcequotas", "status", c.ns, resourceQuota), &api.ResourceQuota{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ResourceQuota), err
|
||||
}
|
||||
|
||||
func (c *FakeResourceQuotas) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("resourcequotas", c.ns, name), &api.ResourceQuota{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeResourceQuotas) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("resourcequotas", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.ResourceQuotaList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeResourceQuotas) Get(name string) (result *api.ResourceQuota, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("resourcequotas", c.ns, name), &api.ResourceQuota{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ResourceQuota), err
|
||||
}
|
||||
|
||||
func (c *FakeResourceQuotas) List(opts api.ListOptions) (result *api.ResourceQuotaList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("resourcequotas", c.ns, opts), &api.ResourceQuotaList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.ResourceQuotaList{}
|
||||
for _, item := range obj.(*api.ResourceQuotaList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested resourceQuotas.
|
||||
func (c *FakeResourceQuotas) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("resourcequotas", c.ns, opts))
|
||||
|
||||
}
|
||||
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_secret.go
generated
vendored
Normal file
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_secret.go
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeSecrets implements SecretInterface
|
||||
type FakeSecrets struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeSecrets) Create(secret *api.Secret) (result *api.Secret, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("secrets", c.ns, secret), &api.Secret{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Secret), err
|
||||
}
|
||||
|
||||
func (c *FakeSecrets) Update(secret *api.Secret) (result *api.Secret, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("secrets", c.ns, secret), &api.Secret{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Secret), err
|
||||
}
|
||||
|
||||
func (c *FakeSecrets) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("secrets", c.ns, name), &api.Secret{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeSecrets) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("secrets", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.SecretList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeSecrets) Get(name string) (result *api.Secret, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("secrets", c.ns, name), &api.Secret{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Secret), err
|
||||
}
|
||||
|
||||
func (c *FakeSecrets) List(opts api.ListOptions) (result *api.SecretList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("secrets", c.ns, opts), &api.SecretList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.SecretList{}
|
||||
for _, item := range obj.(*api.SecretList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested secrets.
|
||||
func (c *FakeSecrets) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("secrets", c.ns, opts))
|
||||
|
||||
}
|
||||
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_service.go
generated
vendored
Normal file
112
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_service.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeServices implements ServiceInterface
|
||||
type FakeServices struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeServices) Create(service *api.Service) (result *api.Service, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("services", c.ns, service), &api.Service{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Service), err
|
||||
}
|
||||
|
||||
func (c *FakeServices) Update(service *api.Service) (result *api.Service, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("services", c.ns, service), &api.Service{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Service), err
|
||||
}
|
||||
|
||||
func (c *FakeServices) UpdateStatus(service *api.Service) (*api.Service, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("services", "status", c.ns, service), &api.Service{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Service), err
|
||||
}
|
||||
|
||||
func (c *FakeServices) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("services", c.ns, name), &api.Service{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeServices) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("services", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.ServiceList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeServices) Get(name string) (result *api.Service, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("services", c.ns, name), &api.Service{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.Service), err
|
||||
}
|
||||
|
||||
func (c *FakeServices) List(opts api.ListOptions) (result *api.ServiceList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("services", c.ns, opts), &api.ServiceList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.ServiceList{}
|
||||
for _, item := range obj.(*api.ServiceList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested services.
|
||||
func (c *FakeServices) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("services", c.ns, opts))
|
||||
|
||||
}
|
||||
26
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_service_expansion.go
generated
vendored
Normal file
26
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_service_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/client/testing/core"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
func (c *FakeServices) ProxyGet(scheme, name, port, path string, params map[string]string) client.ResponseWrapper {
|
||||
return c.Fake.InvokesProxy(core.NewProxyGetAction("services", c.ns, scheme, name, port, path, params))
|
||||
}
|
||||
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_serviceaccount.go
generated
vendored
Normal file
102
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/fake/fake_serviceaccount.go
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeServiceAccounts implements ServiceAccountInterface
|
||||
type FakeServiceAccounts struct {
|
||||
Fake *FakeCore
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeServiceAccounts) Create(serviceAccount *api.ServiceAccount) (result *api.ServiceAccount, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("serviceaccounts", c.ns, serviceAccount), &api.ServiceAccount{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ServiceAccount), err
|
||||
}
|
||||
|
||||
func (c *FakeServiceAccounts) Update(serviceAccount *api.ServiceAccount) (result *api.ServiceAccount, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("serviceaccounts", c.ns, serviceAccount), &api.ServiceAccount{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ServiceAccount), err
|
||||
}
|
||||
|
||||
func (c *FakeServiceAccounts) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("serviceaccounts", c.ns, name), &api.ServiceAccount{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeServiceAccounts) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("serviceaccounts", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &api.ServiceAccountList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeServiceAccounts) Get(name string) (result *api.ServiceAccount, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("serviceaccounts", c.ns, name), &api.ServiceAccount{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*api.ServiceAccount), err
|
||||
}
|
||||
|
||||
func (c *FakeServiceAccounts) List(opts api.ListOptions) (result *api.ServiceAccountList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("serviceaccounts", c.ns, opts), &api.ServiceAccountList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &api.ServiceAccountList{}
|
||||
for _, item := range obj.(*api.ServiceAccountList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested serviceAccounts.
|
||||
func (c *FakeServiceAccounts) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("serviceaccounts", c.ns, opts))
|
||||
|
||||
}
|
||||
41
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/generated_expansion.go
generated
vendored
Normal file
41
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/generated_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
type ComponentStatusExpansion interface{}
|
||||
|
||||
type EndpointsExpansion interface{}
|
||||
|
||||
type LimitRangeExpansion interface{}
|
||||
|
||||
type NodeExpansion interface{}
|
||||
|
||||
type PersistentVolumeExpansion interface{}
|
||||
|
||||
type PersistentVolumeClaimExpansion interface{}
|
||||
|
||||
type PodTemplateExpansion interface{}
|
||||
|
||||
type ReplicationControllerExpansion interface{}
|
||||
|
||||
type ResourceQuotaExpansion interface{}
|
||||
|
||||
type SecretExpansion interface{}
|
||||
|
||||
type ServiceAccountExpansion interface{}
|
||||
|
||||
type ConfigMapExpansion interface{}
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/limitrange.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/limitrange.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// LimitRangesGetter has a method to return a LimitRangeInterface.
|
||||
// A group's client should implement this interface.
|
||||
type LimitRangesGetter interface {
|
||||
LimitRanges(namespace string) LimitRangeInterface
|
||||
}
|
||||
|
||||
// LimitRangeInterface has methods to work with LimitRange resources.
|
||||
type LimitRangeInterface interface {
|
||||
Create(*api.LimitRange) (*api.LimitRange, error)
|
||||
Update(*api.LimitRange) (*api.LimitRange, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.LimitRange, error)
|
||||
List(opts api.ListOptions) (*api.LimitRangeList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
LimitRangeExpansion
|
||||
}
|
||||
|
||||
// limitRanges implements LimitRangeInterface
|
||||
type limitRanges struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newLimitRanges returns a LimitRanges
|
||||
func newLimitRanges(c *CoreClient, namespace string) *limitRanges {
|
||||
return &limitRanges{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a limitRange and creates it. Returns the server's representation of the limitRange, and an error, if there is any.
|
||||
func (c *limitRanges) Create(limitRange *api.LimitRange) (result *api.LimitRange, err error) {
|
||||
result = &api.LimitRange{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("limitranges").
|
||||
Body(limitRange).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a limitRange and updates it. Returns the server's representation of the limitRange, and an error, if there is any.
|
||||
func (c *limitRanges) Update(limitRange *api.LimitRange) (result *api.LimitRange, err error) {
|
||||
result = &api.LimitRange{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("limitranges").
|
||||
Name(limitRange.Name).
|
||||
Body(limitRange).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the limitRange and deletes it. Returns an error if one occurs.
|
||||
func (c *limitRanges) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("limitranges").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *limitRanges) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("limitranges").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the limitRange, and returns the corresponding limitRange object, and an error if there is any.
|
||||
func (c *limitRanges) Get(name string) (result *api.LimitRange, err error) {
|
||||
result = &api.LimitRange{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("limitranges").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of LimitRanges that match those selectors.
|
||||
func (c *limitRanges) List(opts api.ListOptions) (result *api.LimitRangeList, err error) {
|
||||
result = &api.LimitRangeList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("limitranges").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested limitRanges.
|
||||
func (c *limitRanges) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("limitranges").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
139
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/namespace.go
generated
vendored
Normal file
139
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/namespace.go
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// NamespacesGetter has a method to return a NamespaceInterface.
|
||||
// A group's client should implement this interface.
|
||||
type NamespacesGetter interface {
|
||||
Namespaces() NamespaceInterface
|
||||
}
|
||||
|
||||
// NamespaceInterface has methods to work with Namespace resources.
|
||||
type NamespaceInterface interface {
|
||||
Create(*api.Namespace) (*api.Namespace, error)
|
||||
Update(*api.Namespace) (*api.Namespace, error)
|
||||
UpdateStatus(*api.Namespace) (*api.Namespace, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Namespace, error)
|
||||
List(opts api.ListOptions) (*api.NamespaceList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
NamespaceExpansion
|
||||
}
|
||||
|
||||
// namespaces implements NamespaceInterface
|
||||
type namespaces struct {
|
||||
client *CoreClient
|
||||
}
|
||||
|
||||
// newNamespaces returns a Namespaces
|
||||
func newNamespaces(c *CoreClient) *namespaces {
|
||||
return &namespaces{
|
||||
client: c,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a namespace and creates it. Returns the server's representation of the namespace, and an error, if there is any.
|
||||
func (c *namespaces) Create(namespace *api.Namespace) (result *api.Namespace, err error) {
|
||||
result = &api.Namespace{}
|
||||
err = c.client.Post().
|
||||
Resource("namespaces").
|
||||
Body(namespace).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a namespace and updates it. Returns the server's representation of the namespace, and an error, if there is any.
|
||||
func (c *namespaces) Update(namespace *api.Namespace) (result *api.Namespace, err error) {
|
||||
result = &api.Namespace{}
|
||||
err = c.client.Put().
|
||||
Resource("namespaces").
|
||||
Name(namespace.Name).
|
||||
Body(namespace).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *namespaces) UpdateStatus(namespace *api.Namespace) (result *api.Namespace, err error) {
|
||||
result = &api.Namespace{}
|
||||
err = c.client.Put().
|
||||
Resource("namespaces").
|
||||
Name(namespace.Name).
|
||||
SubResource("status").
|
||||
Body(namespace).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the namespace and deletes it. Returns an error if one occurs.
|
||||
func (c *namespaces) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("namespaces").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *namespaces) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("namespaces").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the namespace, and returns the corresponding namespace object, and an error if there is any.
|
||||
func (c *namespaces) Get(name string) (result *api.Namespace, err error) {
|
||||
result = &api.Namespace{}
|
||||
err = c.client.Get().
|
||||
Resource("namespaces").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Namespaces that match those selectors.
|
||||
func (c *namespaces) List(opts api.ListOptions) (result *api.NamespaceList, err error) {
|
||||
result = &api.NamespaceList{}
|
||||
err = c.client.Get().
|
||||
Resource("namespaces").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested namespaces.
|
||||
func (c *namespaces) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Resource("namespaces").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
31
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/namespace_expansion.go
generated
vendored
Normal file
31
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/namespace_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import "k8s.io/kubernetes/pkg/api"
|
||||
|
||||
// The NamespaceExpansion interface allows manually adding extra methods to the NamespaceInterface.
|
||||
type NamespaceExpansion interface {
|
||||
Finalize(item *api.Namespace) (*api.Namespace, error)
|
||||
}
|
||||
|
||||
// Finalize takes the representation of a namespace to update. Returns the server's representation of the namespace, and an error, if it occurs.
|
||||
func (c *namespaces) Finalize(namespace *api.Namespace) (result *api.Namespace, err error) {
|
||||
result = &api.Namespace{}
|
||||
err = c.client.Put().Resource("namespaces").Name(namespace.Name).SubResource("finalize").Body(namespace).Do().Into(result)
|
||||
return
|
||||
}
|
||||
139
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/node.go
generated
vendored
Normal file
139
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/node.go
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// NodesGetter has a method to return a NodeInterface.
|
||||
// A group's client should implement this interface.
|
||||
type NodesGetter interface {
|
||||
Nodes() NodeInterface
|
||||
}
|
||||
|
||||
// NodeInterface has methods to work with Node resources.
|
||||
type NodeInterface interface {
|
||||
Create(*api.Node) (*api.Node, error)
|
||||
Update(*api.Node) (*api.Node, error)
|
||||
UpdateStatus(*api.Node) (*api.Node, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Node, error)
|
||||
List(opts api.ListOptions) (*api.NodeList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
NodeExpansion
|
||||
}
|
||||
|
||||
// nodes implements NodeInterface
|
||||
type nodes struct {
|
||||
client *CoreClient
|
||||
}
|
||||
|
||||
// newNodes returns a Nodes
|
||||
func newNodes(c *CoreClient) *nodes {
|
||||
return &nodes{
|
||||
client: c,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a node and creates it. Returns the server's representation of the node, and an error, if there is any.
|
||||
func (c *nodes) Create(node *api.Node) (result *api.Node, err error) {
|
||||
result = &api.Node{}
|
||||
err = c.client.Post().
|
||||
Resource("nodes").
|
||||
Body(node).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a node and updates it. Returns the server's representation of the node, and an error, if there is any.
|
||||
func (c *nodes) Update(node *api.Node) (result *api.Node, err error) {
|
||||
result = &api.Node{}
|
||||
err = c.client.Put().
|
||||
Resource("nodes").
|
||||
Name(node.Name).
|
||||
Body(node).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *nodes) UpdateStatus(node *api.Node) (result *api.Node, err error) {
|
||||
result = &api.Node{}
|
||||
err = c.client.Put().
|
||||
Resource("nodes").
|
||||
Name(node.Name).
|
||||
SubResource("status").
|
||||
Body(node).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the node and deletes it. Returns an error if one occurs.
|
||||
func (c *nodes) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("nodes").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *nodes) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("nodes").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the node, and returns the corresponding node object, and an error if there is any.
|
||||
func (c *nodes) Get(name string) (result *api.Node, err error) {
|
||||
result = &api.Node{}
|
||||
err = c.client.Get().
|
||||
Resource("nodes").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Nodes that match those selectors.
|
||||
func (c *nodes) List(opts api.ListOptions) (result *api.NodeList, err error) {
|
||||
result = &api.NodeList{}
|
||||
err = c.client.Get().
|
||||
Resource("nodes").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested nodes.
|
||||
func (c *nodes) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Resource("nodes").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
139
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/persistentvolume.go
generated
vendored
Normal file
139
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/persistentvolume.go
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// PersistentVolumesGetter has a method to return a PersistentVolumeInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PersistentVolumesGetter interface {
|
||||
PersistentVolumes() PersistentVolumeInterface
|
||||
}
|
||||
|
||||
// PersistentVolumeInterface has methods to work with PersistentVolume resources.
|
||||
type PersistentVolumeInterface interface {
|
||||
Create(*api.PersistentVolume) (*api.PersistentVolume, error)
|
||||
Update(*api.PersistentVolume) (*api.PersistentVolume, error)
|
||||
UpdateStatus(*api.PersistentVolume) (*api.PersistentVolume, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.PersistentVolume, error)
|
||||
List(opts api.ListOptions) (*api.PersistentVolumeList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
PersistentVolumeExpansion
|
||||
}
|
||||
|
||||
// persistentVolumes implements PersistentVolumeInterface
|
||||
type persistentVolumes struct {
|
||||
client *CoreClient
|
||||
}
|
||||
|
||||
// newPersistentVolumes returns a PersistentVolumes
|
||||
func newPersistentVolumes(c *CoreClient) *persistentVolumes {
|
||||
return &persistentVolumes{
|
||||
client: c,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a persistentVolume and creates it. Returns the server's representation of the persistentVolume, and an error, if there is any.
|
||||
func (c *persistentVolumes) Create(persistentVolume *api.PersistentVolume) (result *api.PersistentVolume, err error) {
|
||||
result = &api.PersistentVolume{}
|
||||
err = c.client.Post().
|
||||
Resource("persistentvolumes").
|
||||
Body(persistentVolume).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a persistentVolume and updates it. Returns the server's representation of the persistentVolume, and an error, if there is any.
|
||||
func (c *persistentVolumes) Update(persistentVolume *api.PersistentVolume) (result *api.PersistentVolume, err error) {
|
||||
result = &api.PersistentVolume{}
|
||||
err = c.client.Put().
|
||||
Resource("persistentvolumes").
|
||||
Name(persistentVolume.Name).
|
||||
Body(persistentVolume).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *persistentVolumes) UpdateStatus(persistentVolume *api.PersistentVolume) (result *api.PersistentVolume, err error) {
|
||||
result = &api.PersistentVolume{}
|
||||
err = c.client.Put().
|
||||
Resource("persistentvolumes").
|
||||
Name(persistentVolume.Name).
|
||||
SubResource("status").
|
||||
Body(persistentVolume).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the persistentVolume and deletes it. Returns an error if one occurs.
|
||||
func (c *persistentVolumes) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("persistentvolumes").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *persistentVolumes) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("persistentvolumes").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the persistentVolume, and returns the corresponding persistentVolume object, and an error if there is any.
|
||||
func (c *persistentVolumes) Get(name string) (result *api.PersistentVolume, err error) {
|
||||
result = &api.PersistentVolume{}
|
||||
err = c.client.Get().
|
||||
Resource("persistentvolumes").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PersistentVolumes that match those selectors.
|
||||
func (c *persistentVolumes) List(opts api.ListOptions) (result *api.PersistentVolumeList, err error) {
|
||||
result = &api.PersistentVolumeList{}
|
||||
err = c.client.Get().
|
||||
Resource("persistentvolumes").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested persistentVolumes.
|
||||
func (c *persistentVolumes) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Resource("persistentvolumes").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/persistentvolumeclaim.go
generated
vendored
Normal file
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/persistentvolumeclaim.go
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// PersistentVolumeClaimsGetter has a method to return a PersistentVolumeClaimInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PersistentVolumeClaimsGetter interface {
|
||||
PersistentVolumeClaims(namespace string) PersistentVolumeClaimInterface
|
||||
}
|
||||
|
||||
// PersistentVolumeClaimInterface has methods to work with PersistentVolumeClaim resources.
|
||||
type PersistentVolumeClaimInterface interface {
|
||||
Create(*api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error)
|
||||
Update(*api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error)
|
||||
UpdateStatus(*api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.PersistentVolumeClaim, error)
|
||||
List(opts api.ListOptions) (*api.PersistentVolumeClaimList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
PersistentVolumeClaimExpansion
|
||||
}
|
||||
|
||||
// persistentVolumeClaims implements PersistentVolumeClaimInterface
|
||||
type persistentVolumeClaims struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newPersistentVolumeClaims returns a PersistentVolumeClaims
|
||||
func newPersistentVolumeClaims(c *CoreClient, namespace string) *persistentVolumeClaims {
|
||||
return &persistentVolumeClaims{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a persistentVolumeClaim and creates it. Returns the server's representation of the persistentVolumeClaim, and an error, if there is any.
|
||||
func (c *persistentVolumeClaims) Create(persistentVolumeClaim *api.PersistentVolumeClaim) (result *api.PersistentVolumeClaim, err error) {
|
||||
result = &api.PersistentVolumeClaim{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
Body(persistentVolumeClaim).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a persistentVolumeClaim and updates it. Returns the server's representation of the persistentVolumeClaim, and an error, if there is any.
|
||||
func (c *persistentVolumeClaims) Update(persistentVolumeClaim *api.PersistentVolumeClaim) (result *api.PersistentVolumeClaim, err error) {
|
||||
result = &api.PersistentVolumeClaim{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
Name(persistentVolumeClaim.Name).
|
||||
Body(persistentVolumeClaim).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *persistentVolumeClaims) UpdateStatus(persistentVolumeClaim *api.PersistentVolumeClaim) (result *api.PersistentVolumeClaim, err error) {
|
||||
result = &api.PersistentVolumeClaim{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
Name(persistentVolumeClaim.Name).
|
||||
SubResource("status").
|
||||
Body(persistentVolumeClaim).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the persistentVolumeClaim and deletes it. Returns an error if one occurs.
|
||||
func (c *persistentVolumeClaims) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *persistentVolumeClaims) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the persistentVolumeClaim, and returns the corresponding persistentVolumeClaim object, and an error if there is any.
|
||||
func (c *persistentVolumeClaims) Get(name string) (result *api.PersistentVolumeClaim, err error) {
|
||||
result = &api.PersistentVolumeClaim{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PersistentVolumeClaims that match those selectors.
|
||||
func (c *persistentVolumeClaims) List(opts api.ListOptions) (result *api.PersistentVolumeClaimList, err error) {
|
||||
result = &api.PersistentVolumeClaimList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested persistentVolumeClaims.
|
||||
func (c *persistentVolumeClaims) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("persistentvolumeclaims").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/pod.go
generated
vendored
Normal file
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/pod.go
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// PodsGetter has a method to return a PodInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PodsGetter interface {
|
||||
Pods(namespace string) PodInterface
|
||||
}
|
||||
|
||||
// PodInterface has methods to work with Pod resources.
|
||||
type PodInterface interface {
|
||||
Create(*api.Pod) (*api.Pod, error)
|
||||
Update(*api.Pod) (*api.Pod, error)
|
||||
UpdateStatus(*api.Pod) (*api.Pod, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Pod, error)
|
||||
List(opts api.ListOptions) (*api.PodList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
PodExpansion
|
||||
}
|
||||
|
||||
// pods implements PodInterface
|
||||
type pods struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newPods returns a Pods
|
||||
func newPods(c *CoreClient, namespace string) *pods {
|
||||
return &pods{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a pod and creates it. Returns the server's representation of the pod, and an error, if there is any.
|
||||
func (c *pods) Create(pod *api.Pod) (result *api.Pod, err error) {
|
||||
result = &api.Pod{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
Body(pod).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a pod and updates it. Returns the server's representation of the pod, and an error, if there is any.
|
||||
func (c *pods) Update(pod *api.Pod) (result *api.Pod, err error) {
|
||||
result = &api.Pod{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
Name(pod.Name).
|
||||
Body(pod).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *pods) UpdateStatus(pod *api.Pod) (result *api.Pod, err error) {
|
||||
result = &api.Pod{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
Name(pod.Name).
|
||||
SubResource("status").
|
||||
Body(pod).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the pod and deletes it. Returns an error if one occurs.
|
||||
func (c *pods) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *pods) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the pod, and returns the corresponding pod object, and an error if there is any.
|
||||
func (c *pods) Get(name string) (result *api.Pod, err error) {
|
||||
result = &api.Pod{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Pods that match those selectors.
|
||||
func (c *pods) List(opts api.ListOptions) (result *api.PodList, err error) {
|
||||
result = &api.PodList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested pods.
|
||||
func (c *pods) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("pods").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
38
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/pod_expansion.go
generated
vendored
Normal file
38
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/pod_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
unversioned "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
// The PodExpansion interface allows manually adding extra methods to the PodInterface.
|
||||
type PodExpansion interface {
|
||||
Bind(binding *api.Binding) error
|
||||
GetLogs(name string, opts *api.PodLogOptions) *unversioned.Request
|
||||
}
|
||||
|
||||
// Bind applies the provided binding to the named pod in the current namespace (binding.Namespace is ignored).
|
||||
func (c *pods) Bind(binding *api.Binding) error {
|
||||
return c.client.Post().Namespace(c.ns).Resource("pods").Name(binding.Name).SubResource("binding").Body(binding).Do().Error()
|
||||
}
|
||||
|
||||
// Get constructs a request for getting the logs for a pod
|
||||
func (c *pods) GetLogs(name string, opts *api.PodLogOptions) *unversioned.Request {
|
||||
return c.client.Get().Namespace(c.ns).Name(name).Resource("pods").SubResource("log").VersionedParams(opts, api.ParameterCodec)
|
||||
}
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/podtemplate.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/podtemplate.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// PodTemplatesGetter has a method to return a PodTemplateInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PodTemplatesGetter interface {
|
||||
PodTemplates(namespace string) PodTemplateInterface
|
||||
}
|
||||
|
||||
// PodTemplateInterface has methods to work with PodTemplate resources.
|
||||
type PodTemplateInterface interface {
|
||||
Create(*api.PodTemplate) (*api.PodTemplate, error)
|
||||
Update(*api.PodTemplate) (*api.PodTemplate, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.PodTemplate, error)
|
||||
List(opts api.ListOptions) (*api.PodTemplateList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
PodTemplateExpansion
|
||||
}
|
||||
|
||||
// podTemplates implements PodTemplateInterface
|
||||
type podTemplates struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newPodTemplates returns a PodTemplates
|
||||
func newPodTemplates(c *CoreClient, namespace string) *podTemplates {
|
||||
return &podTemplates{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a podTemplate and creates it. Returns the server's representation of the podTemplate, and an error, if there is any.
|
||||
func (c *podTemplates) Create(podTemplate *api.PodTemplate) (result *api.PodTemplate, err error) {
|
||||
result = &api.PodTemplate{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("podtemplates").
|
||||
Body(podTemplate).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a podTemplate and updates it. Returns the server's representation of the podTemplate, and an error, if there is any.
|
||||
func (c *podTemplates) Update(podTemplate *api.PodTemplate) (result *api.PodTemplate, err error) {
|
||||
result = &api.PodTemplate{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("podtemplates").
|
||||
Name(podTemplate.Name).
|
||||
Body(podTemplate).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the podTemplate and deletes it. Returns an error if one occurs.
|
||||
func (c *podTemplates) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("podtemplates").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *podTemplates) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("podtemplates").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the podTemplate, and returns the corresponding podTemplate object, and an error if there is any.
|
||||
func (c *podTemplates) Get(name string) (result *api.PodTemplate, err error) {
|
||||
result = &api.PodTemplate{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("podtemplates").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PodTemplates that match those selectors.
|
||||
func (c *podTemplates) List(opts api.ListOptions) (result *api.PodTemplateList, err error) {
|
||||
result = &api.PodTemplateList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("podtemplates").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested podTemplates.
|
||||
func (c *podTemplates) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("podtemplates").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/replicationcontroller.go
generated
vendored
Normal file
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/replicationcontroller.go
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ReplicationControllersGetter has a method to return a ReplicationControllerInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ReplicationControllersGetter interface {
|
||||
ReplicationControllers(namespace string) ReplicationControllerInterface
|
||||
}
|
||||
|
||||
// ReplicationControllerInterface has methods to work with ReplicationController resources.
|
||||
type ReplicationControllerInterface interface {
|
||||
Create(*api.ReplicationController) (*api.ReplicationController, error)
|
||||
Update(*api.ReplicationController) (*api.ReplicationController, error)
|
||||
UpdateStatus(*api.ReplicationController) (*api.ReplicationController, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.ReplicationController, error)
|
||||
List(opts api.ListOptions) (*api.ReplicationControllerList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
ReplicationControllerExpansion
|
||||
}
|
||||
|
||||
// replicationControllers implements ReplicationControllerInterface
|
||||
type replicationControllers struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newReplicationControllers returns a ReplicationControllers
|
||||
func newReplicationControllers(c *CoreClient, namespace string) *replicationControllers {
|
||||
return &replicationControllers{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a replicationController and creates it. Returns the server's representation of the replicationController, and an error, if there is any.
|
||||
func (c *replicationControllers) Create(replicationController *api.ReplicationController) (result *api.ReplicationController, err error) {
|
||||
result = &api.ReplicationController{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
Body(replicationController).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a replicationController and updates it. Returns the server's representation of the replicationController, and an error, if there is any.
|
||||
func (c *replicationControllers) Update(replicationController *api.ReplicationController) (result *api.ReplicationController, err error) {
|
||||
result = &api.ReplicationController{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
Name(replicationController.Name).
|
||||
Body(replicationController).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *replicationControllers) UpdateStatus(replicationController *api.ReplicationController) (result *api.ReplicationController, err error) {
|
||||
result = &api.ReplicationController{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
Name(replicationController.Name).
|
||||
SubResource("status").
|
||||
Body(replicationController).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the replicationController and deletes it. Returns an error if one occurs.
|
||||
func (c *replicationControllers) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *replicationControllers) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the replicationController, and returns the corresponding replicationController object, and an error if there is any.
|
||||
func (c *replicationControllers) Get(name string) (result *api.ReplicationController, err error) {
|
||||
result = &api.ReplicationController{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ReplicationControllers that match those selectors.
|
||||
func (c *replicationControllers) List(opts api.ListOptions) (result *api.ReplicationControllerList, err error) {
|
||||
result = &api.ReplicationControllerList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested replicationControllers.
|
||||
func (c *replicationControllers) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("replicationcontrollers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/resourcequota.go
generated
vendored
Normal file
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/resourcequota.go
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ResourceQuotasGetter has a method to return a ResourceQuotaInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ResourceQuotasGetter interface {
|
||||
ResourceQuotas(namespace string) ResourceQuotaInterface
|
||||
}
|
||||
|
||||
// ResourceQuotaInterface has methods to work with ResourceQuota resources.
|
||||
type ResourceQuotaInterface interface {
|
||||
Create(*api.ResourceQuota) (*api.ResourceQuota, error)
|
||||
Update(*api.ResourceQuota) (*api.ResourceQuota, error)
|
||||
UpdateStatus(*api.ResourceQuota) (*api.ResourceQuota, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.ResourceQuota, error)
|
||||
List(opts api.ListOptions) (*api.ResourceQuotaList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
ResourceQuotaExpansion
|
||||
}
|
||||
|
||||
// resourceQuotas implements ResourceQuotaInterface
|
||||
type resourceQuotas struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newResourceQuotas returns a ResourceQuotas
|
||||
func newResourceQuotas(c *CoreClient, namespace string) *resourceQuotas {
|
||||
return &resourceQuotas{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a resourceQuota and creates it. Returns the server's representation of the resourceQuota, and an error, if there is any.
|
||||
func (c *resourceQuotas) Create(resourceQuota *api.ResourceQuota) (result *api.ResourceQuota, err error) {
|
||||
result = &api.ResourceQuota{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
Body(resourceQuota).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a resourceQuota and updates it. Returns the server's representation of the resourceQuota, and an error, if there is any.
|
||||
func (c *resourceQuotas) Update(resourceQuota *api.ResourceQuota) (result *api.ResourceQuota, err error) {
|
||||
result = &api.ResourceQuota{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
Name(resourceQuota.Name).
|
||||
Body(resourceQuota).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *resourceQuotas) UpdateStatus(resourceQuota *api.ResourceQuota) (result *api.ResourceQuota, err error) {
|
||||
result = &api.ResourceQuota{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
Name(resourceQuota.Name).
|
||||
SubResource("status").
|
||||
Body(resourceQuota).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the resourceQuota and deletes it. Returns an error if one occurs.
|
||||
func (c *resourceQuotas) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *resourceQuotas) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the resourceQuota, and returns the corresponding resourceQuota object, and an error if there is any.
|
||||
func (c *resourceQuotas) Get(name string) (result *api.ResourceQuota, err error) {
|
||||
result = &api.ResourceQuota{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ResourceQuotas that match those selectors.
|
||||
func (c *resourceQuotas) List(opts api.ListOptions) (result *api.ResourceQuotaList, err error) {
|
||||
result = &api.ResourceQuotaList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested resourceQuotas.
|
||||
func (c *resourceQuotas) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("resourcequotas").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/secret.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/secret.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// SecretsGetter has a method to return a SecretInterface.
|
||||
// A group's client should implement this interface.
|
||||
type SecretsGetter interface {
|
||||
Secrets(namespace string) SecretInterface
|
||||
}
|
||||
|
||||
// SecretInterface has methods to work with Secret resources.
|
||||
type SecretInterface interface {
|
||||
Create(*api.Secret) (*api.Secret, error)
|
||||
Update(*api.Secret) (*api.Secret, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Secret, error)
|
||||
List(opts api.ListOptions) (*api.SecretList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
SecretExpansion
|
||||
}
|
||||
|
||||
// secrets implements SecretInterface
|
||||
type secrets struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newSecrets returns a Secrets
|
||||
func newSecrets(c *CoreClient, namespace string) *secrets {
|
||||
return &secrets{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a secret and creates it. Returns the server's representation of the secret, and an error, if there is any.
|
||||
func (c *secrets) Create(secret *api.Secret) (result *api.Secret, err error) {
|
||||
result = &api.Secret{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("secrets").
|
||||
Body(secret).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a secret and updates it. Returns the server's representation of the secret, and an error, if there is any.
|
||||
func (c *secrets) Update(secret *api.Secret) (result *api.Secret, err error) {
|
||||
result = &api.Secret{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("secrets").
|
||||
Name(secret.Name).
|
||||
Body(secret).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the secret and deletes it. Returns an error if one occurs.
|
||||
func (c *secrets) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("secrets").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *secrets) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("secrets").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the secret, and returns the corresponding secret object, and an error if there is any.
|
||||
func (c *secrets) Get(name string) (result *api.Secret, err error) {
|
||||
result = &api.Secret{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("secrets").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Secrets that match those selectors.
|
||||
func (c *secrets) List(opts api.ListOptions) (result *api.SecretList, err error) {
|
||||
result = &api.SecretList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("secrets").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested secrets.
|
||||
func (c *secrets) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("secrets").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/service.go
generated
vendored
Normal file
149
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/service.go
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ServicesGetter has a method to return a ServiceInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ServicesGetter interface {
|
||||
Services(namespace string) ServiceInterface
|
||||
}
|
||||
|
||||
// ServiceInterface has methods to work with Service resources.
|
||||
type ServiceInterface interface {
|
||||
Create(*api.Service) (*api.Service, error)
|
||||
Update(*api.Service) (*api.Service, error)
|
||||
UpdateStatus(*api.Service) (*api.Service, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.Service, error)
|
||||
List(opts api.ListOptions) (*api.ServiceList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
ServiceExpansion
|
||||
}
|
||||
|
||||
// services implements ServiceInterface
|
||||
type services struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newServices returns a Services
|
||||
func newServices(c *CoreClient, namespace string) *services {
|
||||
return &services{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a service and creates it. Returns the server's representation of the service, and an error, if there is any.
|
||||
func (c *services) Create(service *api.Service) (result *api.Service, err error) {
|
||||
result = &api.Service{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
Body(service).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a service and updates it. Returns the server's representation of the service, and an error, if there is any.
|
||||
func (c *services) Update(service *api.Service) (result *api.Service, err error) {
|
||||
result = &api.Service{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
Name(service.Name).
|
||||
Body(service).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *services) UpdateStatus(service *api.Service) (result *api.Service, err error) {
|
||||
result = &api.Service{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
Name(service.Name).
|
||||
SubResource("status").
|
||||
Body(service).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the service and deletes it. Returns an error if one occurs.
|
||||
func (c *services) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *services) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the service, and returns the corresponding service object, and an error if there is any.
|
||||
func (c *services) Get(name string) (result *api.Service, err error) {
|
||||
result = &api.Service{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Services that match those selectors.
|
||||
func (c *services) List(opts api.ListOptions) (result *api.ServiceList, err error) {
|
||||
result = &api.ServiceList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested services.
|
||||
func (c *services) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
41
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/service_expansion.go
generated
vendored
Normal file
41
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/service_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/util/net"
|
||||
)
|
||||
|
||||
// The ServiceExpansion interface allows manually adding extra methods to the ServiceInterface.
|
||||
type ServiceExpansion interface {
|
||||
ProxyGet(scheme, name, port, path string, params map[string]string) unversioned.ResponseWrapper
|
||||
}
|
||||
|
||||
// ProxyGet returns a response of the service by calling it through the proxy.
|
||||
func (c *services) ProxyGet(scheme, name, port, path string, params map[string]string) unversioned.ResponseWrapper {
|
||||
request := c.client.Get().
|
||||
Prefix("proxy").
|
||||
Namespace(c.ns).
|
||||
Resource("services").
|
||||
Name(net.JoinSchemeNamePort(scheme, name, port)).
|
||||
Suffix(path)
|
||||
for k, v := range params {
|
||||
request = request.Param(k, v)
|
||||
}
|
||||
return request
|
||||
}
|
||||
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/serviceaccount.go
generated
vendored
Normal file
135
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned/serviceaccount.go
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// ServiceAccountsGetter has a method to return a ServiceAccountInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ServiceAccountsGetter interface {
|
||||
ServiceAccounts(namespace string) ServiceAccountInterface
|
||||
}
|
||||
|
||||
// ServiceAccountInterface has methods to work with ServiceAccount resources.
|
||||
type ServiceAccountInterface interface {
|
||||
Create(*api.ServiceAccount) (*api.ServiceAccount, error)
|
||||
Update(*api.ServiceAccount) (*api.ServiceAccount, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*api.ServiceAccount, error)
|
||||
List(opts api.ListOptions) (*api.ServiceAccountList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
ServiceAccountExpansion
|
||||
}
|
||||
|
||||
// serviceAccounts implements ServiceAccountInterface
|
||||
type serviceAccounts struct {
|
||||
client *CoreClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newServiceAccounts returns a ServiceAccounts
|
||||
func newServiceAccounts(c *CoreClient, namespace string) *serviceAccounts {
|
||||
return &serviceAccounts{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a serviceAccount and creates it. Returns the server's representation of the serviceAccount, and an error, if there is any.
|
||||
func (c *serviceAccounts) Create(serviceAccount *api.ServiceAccount) (result *api.ServiceAccount, err error) {
|
||||
result = &api.ServiceAccount{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("serviceaccounts").
|
||||
Body(serviceAccount).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a serviceAccount and updates it. Returns the server's representation of the serviceAccount, and an error, if there is any.
|
||||
func (c *serviceAccounts) Update(serviceAccount *api.ServiceAccount) (result *api.ServiceAccount, err error) {
|
||||
result = &api.ServiceAccount{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("serviceaccounts").
|
||||
Name(serviceAccount.Name).
|
||||
Body(serviceAccount).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the serviceAccount and deletes it. Returns an error if one occurs.
|
||||
func (c *serviceAccounts) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("serviceaccounts").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *serviceAccounts) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("serviceaccounts").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the serviceAccount, and returns the corresponding serviceAccount object, and an error if there is any.
|
||||
func (c *serviceAccounts) Get(name string) (result *api.ServiceAccount, err error) {
|
||||
result = &api.ServiceAccount{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("serviceaccounts").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of ServiceAccounts that match those selectors.
|
||||
func (c *serviceAccounts) List(opts api.ListOptions) (result *api.ServiceAccountList, err error) {
|
||||
result = &api.ServiceAccountList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("serviceaccounts").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested serviceAccounts.
|
||||
func (c *serviceAccounts) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("serviceaccounts").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
150
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/daemonset.go
generated
vendored
Normal file
150
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/daemonset.go
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// DaemonSetsGetter has a method to return a DaemonSetInterface.
|
||||
// A group's client should implement this interface.
|
||||
type DaemonSetsGetter interface {
|
||||
DaemonSets(namespace string) DaemonSetInterface
|
||||
}
|
||||
|
||||
// DaemonSetInterface has methods to work with DaemonSet resources.
|
||||
type DaemonSetInterface interface {
|
||||
Create(*extensions.DaemonSet) (*extensions.DaemonSet, error)
|
||||
Update(*extensions.DaemonSet) (*extensions.DaemonSet, error)
|
||||
UpdateStatus(*extensions.DaemonSet) (*extensions.DaemonSet, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*extensions.DaemonSet, error)
|
||||
List(opts api.ListOptions) (*extensions.DaemonSetList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
DaemonSetExpansion
|
||||
}
|
||||
|
||||
// daemonSets implements DaemonSetInterface
|
||||
type daemonSets struct {
|
||||
client *ExtensionsClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newDaemonSets returns a DaemonSets
|
||||
func newDaemonSets(c *ExtensionsClient, namespace string) *daemonSets {
|
||||
return &daemonSets{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a daemonSet and creates it. Returns the server's representation of the daemonSet, and an error, if there is any.
|
||||
func (c *daemonSets) Create(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) {
|
||||
result = &extensions.DaemonSet{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
Body(daemonSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a daemonSet and updates it. Returns the server's representation of the daemonSet, and an error, if there is any.
|
||||
func (c *daemonSets) Update(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) {
|
||||
result = &extensions.DaemonSet{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
Name(daemonSet.Name).
|
||||
Body(daemonSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *daemonSets) UpdateStatus(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) {
|
||||
result = &extensions.DaemonSet{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
Name(daemonSet.Name).
|
||||
SubResource("status").
|
||||
Body(daemonSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the daemonSet and deletes it. Returns an error if one occurs.
|
||||
func (c *daemonSets) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *daemonSets) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the daemonSet, and returns the corresponding daemonSet object, and an error if there is any.
|
||||
func (c *daemonSets) Get(name string) (result *extensions.DaemonSet, err error) {
|
||||
result = &extensions.DaemonSet{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of DaemonSets that match those selectors.
|
||||
func (c *daemonSets) List(opts api.ListOptions) (result *extensions.DaemonSetList, err error) {
|
||||
result = &extensions.DaemonSetList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested daemonSets.
|
||||
func (c *daemonSets) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("daemonsets").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
150
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/deployment.go
generated
vendored
Normal file
150
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/deployment.go
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// DeploymentsGetter has a method to return a DeploymentInterface.
|
||||
// A group's client should implement this interface.
|
||||
type DeploymentsGetter interface {
|
||||
Deployments(namespace string) DeploymentInterface
|
||||
}
|
||||
|
||||
// DeploymentInterface has methods to work with Deployment resources.
|
||||
type DeploymentInterface interface {
|
||||
Create(*extensions.Deployment) (*extensions.Deployment, error)
|
||||
Update(*extensions.Deployment) (*extensions.Deployment, error)
|
||||
UpdateStatus(*extensions.Deployment) (*extensions.Deployment, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*extensions.Deployment, error)
|
||||
List(opts api.ListOptions) (*extensions.DeploymentList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
DeploymentExpansion
|
||||
}
|
||||
|
||||
// deployments implements DeploymentInterface
|
||||
type deployments struct {
|
||||
client *ExtensionsClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newDeployments returns a Deployments
|
||||
func newDeployments(c *ExtensionsClient, namespace string) *deployments {
|
||||
return &deployments{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a deployment and creates it. Returns the server's representation of the deployment, and an error, if there is any.
|
||||
func (c *deployments) Create(deployment *extensions.Deployment) (result *extensions.Deployment, err error) {
|
||||
result = &extensions.Deployment{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
Body(deployment).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a deployment and updates it. Returns the server's representation of the deployment, and an error, if there is any.
|
||||
func (c *deployments) Update(deployment *extensions.Deployment) (result *extensions.Deployment, err error) {
|
||||
result = &extensions.Deployment{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
Name(deployment.Name).
|
||||
Body(deployment).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *deployments) UpdateStatus(deployment *extensions.Deployment) (result *extensions.Deployment, err error) {
|
||||
result = &extensions.Deployment{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
Name(deployment.Name).
|
||||
SubResource("status").
|
||||
Body(deployment).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the deployment and deletes it. Returns an error if one occurs.
|
||||
func (c *deployments) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *deployments) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any.
|
||||
func (c *deployments) Get(name string) (result *extensions.Deployment, err error) {
|
||||
result = &extensions.Deployment{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Deployments that match those selectors.
|
||||
func (c *deployments) List(opts api.ListOptions) (result *extensions.DeploymentList, err error) {
|
||||
result = &extensions.DeploymentList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested deployments.
|
||||
func (c *deployments) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("deployments").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
29
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/deployment_expansion.go
generated
vendored
Normal file
29
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/deployment_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
|
||||
// The DeploymentExpansion interface allows manually adding extra methods to the DeploymentInterface.
|
||||
type DeploymentExpansion interface {
|
||||
Rollback(*extensions.DeploymentRollback) error
|
||||
}
|
||||
|
||||
// Rollback applied the provided DeploymentRollback to the named deployment in the current namespace.
|
||||
func (c *deployments) Rollback(deploymentRollback *extensions.DeploymentRollback) error {
|
||||
return c.client.Post().Namespace(c.ns).Resource("deployments").Name(deploymentRollback.Name).SubResource("rollback").Body(deploymentRollback).Do().Error()
|
||||
}
|
||||
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/doc.go
generated
vendored
Normal file
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned has the automatically generated clients for unversioned resources.
|
||||
package unversioned
|
||||
125
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/extensions_client.go
generated
vendored
Normal file
125
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/extensions_client.go
generated
vendored
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
unversioned "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
type ExtensionsInterface interface {
|
||||
DaemonSetsGetter
|
||||
DeploymentsGetter
|
||||
HorizontalPodAutoscalersGetter
|
||||
IngressesGetter
|
||||
JobsGetter
|
||||
ReplicaSetsGetter
|
||||
ScalesGetter
|
||||
ThirdPartyResourcesGetter
|
||||
}
|
||||
|
||||
// ExtensionsClient is used to interact with features provided by the Extensions group.
|
||||
type ExtensionsClient struct {
|
||||
*unversioned.RESTClient
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) DaemonSets(namespace string) DaemonSetInterface {
|
||||
return newDaemonSets(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Deployments(namespace string) DeploymentInterface {
|
||||
return newDeployments(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface {
|
||||
return newHorizontalPodAutoscalers(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Ingresses(namespace string) IngressInterface {
|
||||
return newIngresses(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Jobs(namespace string) JobInterface {
|
||||
return newJobs(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) ReplicaSets(namespace string) ReplicaSetInterface {
|
||||
return newReplicaSets(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Scales(namespace string) ScaleInterface {
|
||||
return newScales(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) ThirdPartyResources(namespace string) ThirdPartyResourceInterface {
|
||||
return newThirdPartyResources(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ExtensionsClient for the given config.
|
||||
func NewForConfig(c *unversioned.Config) (*ExtensionsClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := unversioned.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ExtensionsClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new ExtensionsClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *unversioned.Config) *ExtensionsClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new ExtensionsClient for the given RESTClient.
|
||||
func New(c *unversioned.RESTClient) *ExtensionsClient {
|
||||
return &ExtensionsClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *unversioned.Config) error {
|
||||
// if extensions group is not registered, return an error
|
||||
g, err := registered.Group("extensions")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = unversioned.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.Codec = api.Codecs.LegacyCodec(*config.GroupVersion)
|
||||
if config.QPS == 0 {
|
||||
config.QPS = 5
|
||||
}
|
||||
if config.Burst == 0 {
|
||||
config.Burst = 10
|
||||
}
|
||||
return nil
|
||||
}
|
||||
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/doc.go
generated
vendored
Normal file
18
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake has the automatically generated clients.
|
||||
package fake
|
||||
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_daemonset.go
generated
vendored
Normal file
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_daemonset.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeDaemonSets implements DaemonSetInterface
|
||||
type FakeDaemonSets struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeDaemonSets) Create(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("daemonsets", c.ns, daemonSet), &extensions.DaemonSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.DaemonSet), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemonSets) Update(daemonSet *extensions.DaemonSet) (result *extensions.DaemonSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("daemonsets", c.ns, daemonSet), &extensions.DaemonSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.DaemonSet), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemonSets) UpdateStatus(daemonSet *extensions.DaemonSet) (*extensions.DaemonSet, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("daemonsets", "status", c.ns, daemonSet), &extensions.DaemonSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.DaemonSet), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemonSets) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("daemonsets", c.ns, name), &extensions.DaemonSet{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeDaemonSets) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("daemonsets", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &extensions.DaemonSetList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeDaemonSets) Get(name string) (result *extensions.DaemonSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("daemonsets", c.ns, name), &extensions.DaemonSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.DaemonSet), err
|
||||
}
|
||||
|
||||
func (c *FakeDaemonSets) List(opts api.ListOptions) (result *extensions.DaemonSetList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("daemonsets", c.ns, opts), &extensions.DaemonSetList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &extensions.DaemonSetList{}
|
||||
for _, item := range obj.(*extensions.DaemonSetList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested daemonSets.
|
||||
func (c *FakeDaemonSets) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("daemonsets", c.ns, opts))
|
||||
|
||||
}
|
||||
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_deployment.go
generated
vendored
Normal file
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_deployment.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeDeployments implements DeploymentInterface
|
||||
type FakeDeployments struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeDeployments) Create(deployment *extensions.Deployment) (result *extensions.Deployment, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("deployments", c.ns, deployment), &extensions.Deployment{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Deployment), err
|
||||
}
|
||||
|
||||
func (c *FakeDeployments) Update(deployment *extensions.Deployment) (result *extensions.Deployment, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("deployments", c.ns, deployment), &extensions.Deployment{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Deployment), err
|
||||
}
|
||||
|
||||
func (c *FakeDeployments) UpdateStatus(deployment *extensions.Deployment) (*extensions.Deployment, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("deployments", "status", c.ns, deployment), &extensions.Deployment{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Deployment), err
|
||||
}
|
||||
|
||||
func (c *FakeDeployments) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("deployments", c.ns, name), &extensions.Deployment{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeDeployments) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("deployments", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &extensions.DeploymentList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeDeployments) Get(name string) (result *extensions.Deployment, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("deployments", c.ns, name), &extensions.Deployment{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Deployment), err
|
||||
}
|
||||
|
||||
func (c *FakeDeployments) List(opts api.ListOptions) (result *extensions.DeploymentList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("deployments", c.ns, opts), &extensions.DeploymentList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &extensions.DeploymentList{}
|
||||
for _, item := range obj.(*extensions.DeploymentList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested deployments.
|
||||
func (c *FakeDeployments) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("deployments", c.ns, opts))
|
||||
|
||||
}
|
||||
33
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_deployment_expansion.go
generated
vendored
Normal file
33
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_deployment_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/testing/core"
|
||||
)
|
||||
|
||||
func (c *FakeDeployments) Rollback(deploymentRollback *extensions.DeploymentRollback) error {
|
||||
action := core.CreateActionImpl{}
|
||||
action.Verb = "create"
|
||||
action.Resource = "deployments"
|
||||
action.Subresource = "rollback"
|
||||
action.Object = deploymentRollback
|
||||
|
||||
_, err := c.Fake.Invokes(action, deploymentRollback)
|
||||
return err
|
||||
}
|
||||
58
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_extensions_client.go
generated
vendored
Normal file
58
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_extensions_client.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
unversioned "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned"
|
||||
)
|
||||
|
||||
type FakeExtensions struct {
|
||||
*core.Fake
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) DaemonSets(namespace string) unversioned.DaemonSetInterface {
|
||||
return &FakeDaemonSets{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Deployments(namespace string) unversioned.DeploymentInterface {
|
||||
return &FakeDeployments{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) HorizontalPodAutoscalers(namespace string) unversioned.HorizontalPodAutoscalerInterface {
|
||||
return &FakeHorizontalPodAutoscalers{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Ingresses(namespace string) unversioned.IngressInterface {
|
||||
return &FakeIngresses{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Jobs(namespace string) unversioned.JobInterface {
|
||||
return &FakeJobs{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) ReplicaSets(namespace string) unversioned.ReplicaSetInterface {
|
||||
return &FakeReplicaSets{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Scales(namespace string) unversioned.ScaleInterface {
|
||||
return &FakeScales{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) ThirdPartyResources(namespace string) unversioned.ThirdPartyResourceInterface {
|
||||
return &FakeThirdPartyResources{c, namespace}
|
||||
}
|
||||
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_horizontalpodautoscaler.go
generated
vendored
Normal file
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_horizontalpodautoscaler.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeHorizontalPodAutoscalers implements HorizontalPodAutoscalerInterface
|
||||
type FakeHorizontalPodAutoscalers struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeHorizontalPodAutoscalers) Create(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (result *extensions.HorizontalPodAutoscaler, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("horizontalpodautoscalers", c.ns, horizontalPodAutoscaler), &extensions.HorizontalPodAutoscaler{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.HorizontalPodAutoscaler), err
|
||||
}
|
||||
|
||||
func (c *FakeHorizontalPodAutoscalers) Update(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (result *extensions.HorizontalPodAutoscaler, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("horizontalpodautoscalers", c.ns, horizontalPodAutoscaler), &extensions.HorizontalPodAutoscaler{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.HorizontalPodAutoscaler), err
|
||||
}
|
||||
|
||||
func (c *FakeHorizontalPodAutoscalers) UpdateStatus(horizontalPodAutoscaler *extensions.HorizontalPodAutoscaler) (*extensions.HorizontalPodAutoscaler, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("horizontalpodautoscalers", "status", c.ns, horizontalPodAutoscaler), &extensions.HorizontalPodAutoscaler{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.HorizontalPodAutoscaler), err
|
||||
}
|
||||
|
||||
func (c *FakeHorizontalPodAutoscalers) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("horizontalpodautoscalers", c.ns, name), &extensions.HorizontalPodAutoscaler{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeHorizontalPodAutoscalers) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("horizontalpodautoscalers", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &extensions.HorizontalPodAutoscalerList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeHorizontalPodAutoscalers) Get(name string) (result *extensions.HorizontalPodAutoscaler, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("horizontalpodautoscalers", c.ns, name), &extensions.HorizontalPodAutoscaler{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.HorizontalPodAutoscaler), err
|
||||
}
|
||||
|
||||
func (c *FakeHorizontalPodAutoscalers) List(opts api.ListOptions) (result *extensions.HorizontalPodAutoscalerList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("horizontalpodautoscalers", c.ns, opts), &extensions.HorizontalPodAutoscalerList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &extensions.HorizontalPodAutoscalerList{}
|
||||
for _, item := range obj.(*extensions.HorizontalPodAutoscalerList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested horizontalPodAutoscalers.
|
||||
func (c *FakeHorizontalPodAutoscalers) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("horizontalpodautoscalers", c.ns, opts))
|
||||
|
||||
}
|
||||
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_ingress.go
generated
vendored
Normal file
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_ingress.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeIngresses implements IngressInterface
|
||||
type FakeIngresses struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeIngresses) Create(ingress *extensions.Ingress) (result *extensions.Ingress, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("ingresses", c.ns, ingress), &extensions.Ingress{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Ingress), err
|
||||
}
|
||||
|
||||
func (c *FakeIngresses) Update(ingress *extensions.Ingress) (result *extensions.Ingress, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("ingresses", c.ns, ingress), &extensions.Ingress{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Ingress), err
|
||||
}
|
||||
|
||||
func (c *FakeIngresses) UpdateStatus(ingress *extensions.Ingress) (*extensions.Ingress, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("ingresses", "status", c.ns, ingress), &extensions.Ingress{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Ingress), err
|
||||
}
|
||||
|
||||
func (c *FakeIngresses) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("ingresses", c.ns, name), &extensions.Ingress{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeIngresses) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("ingresses", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &extensions.IngressList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeIngresses) Get(name string) (result *extensions.Ingress, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("ingresses", c.ns, name), &extensions.Ingress{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Ingress), err
|
||||
}
|
||||
|
||||
func (c *FakeIngresses) List(opts api.ListOptions) (result *extensions.IngressList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("ingresses", c.ns, opts), &extensions.IngressList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &extensions.IngressList{}
|
||||
for _, item := range obj.(*extensions.IngressList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested ingresses.
|
||||
func (c *FakeIngresses) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("ingresses", c.ns, opts))
|
||||
|
||||
}
|
||||
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_job.go
generated
vendored
Normal file
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_job.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeJobs implements JobInterface
|
||||
type FakeJobs struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Create(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("jobs", c.ns, job), &extensions.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Update(job *extensions.Job) (result *extensions.Job, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("jobs", c.ns, job), &extensions.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) UpdateStatus(job *extensions.Job) (*extensions.Job, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("jobs", "status", c.ns, job), &extensions.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("jobs", c.ns, name), &extensions.Job{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("jobs", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &extensions.JobList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Get(name string) (result *extensions.Job, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("jobs", c.ns, name), &extensions.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) List(opts api.ListOptions) (result *extensions.JobList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("jobs", c.ns, opts), &extensions.JobList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &extensions.JobList{}
|
||||
for _, item := range obj.(*extensions.JobList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested jobs.
|
||||
func (c *FakeJobs) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("jobs", c.ns, opts))
|
||||
|
||||
}
|
||||
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_replicaset.go
generated
vendored
Normal file
113
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_replicaset.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeReplicaSets implements ReplicaSetInterface
|
||||
type FakeReplicaSets struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeReplicaSets) Create(replicaSet *extensions.ReplicaSet) (result *extensions.ReplicaSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("replicasets", c.ns, replicaSet), &extensions.ReplicaSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.ReplicaSet), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicaSets) Update(replicaSet *extensions.ReplicaSet) (result *extensions.ReplicaSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("replicasets", c.ns, replicaSet), &extensions.ReplicaSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.ReplicaSet), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicaSets) UpdateStatus(replicaSet *extensions.ReplicaSet) (*extensions.ReplicaSet, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateSubresourceAction("replicasets", "status", c.ns, replicaSet), &extensions.ReplicaSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.ReplicaSet), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicaSets) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("replicasets", c.ns, name), &extensions.ReplicaSet{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeReplicaSets) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("replicasets", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &extensions.ReplicaSetList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeReplicaSets) Get(name string) (result *extensions.ReplicaSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("replicasets", c.ns, name), &extensions.ReplicaSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.ReplicaSet), err
|
||||
}
|
||||
|
||||
func (c *FakeReplicaSets) List(opts api.ListOptions) (result *extensions.ReplicaSetList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("replicasets", c.ns, opts), &extensions.ReplicaSetList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &extensions.ReplicaSetList{}
|
||||
for _, item := range obj.(*extensions.ReplicaSetList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested replicaSets.
|
||||
func (c *FakeReplicaSets) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("replicasets", c.ns, opts))
|
||||
|
||||
}
|
||||
23
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_scale.go
generated
vendored
Normal file
23
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_scale.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
// FakeScales implements ScaleInterface
|
||||
type FakeScales struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
46
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_scale_expansion.go
generated
vendored
Normal file
46
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_scale_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/testing/core"
|
||||
)
|
||||
|
||||
func (c *FakeScales) Get(kind string, name string) (result *extensions.Scale, err error) {
|
||||
action := core.GetActionImpl{}
|
||||
action.Verb = "get"
|
||||
action.Namespace = c.ns
|
||||
action.Resource = kind
|
||||
action.Subresource = "scale"
|
||||
action.Name = name
|
||||
obj, err := c.Fake.Invokes(action, &extensions.Scale{})
|
||||
result = obj.(*extensions.Scale)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *FakeScales) Update(kind string, scale *extensions.Scale) (result *extensions.Scale, err error) {
|
||||
action := core.UpdateActionImpl{}
|
||||
action.Verb = "update"
|
||||
action.Namespace = c.ns
|
||||
action.Resource = kind
|
||||
action.Subresource = "scale"
|
||||
action.Object = scale
|
||||
obj, err := c.Fake.Invokes(action, scale)
|
||||
result = obj.(*extensions.Scale)
|
||||
return
|
||||
}
|
||||
103
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_thirdpartyresource.go
generated
vendored
Normal file
103
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake/fake_thirdpartyresource.go
generated
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 fake
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/api"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
core "k8s.io/kubernetes/pkg/client/testing/core"
|
||||
labels "k8s.io/kubernetes/pkg/labels"
|
||||
watch "k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakeThirdPartyResources implements ThirdPartyResourceInterface
|
||||
type FakeThirdPartyResources struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
func (c *FakeThirdPartyResources) Create(thirdPartyResource *extensions.ThirdPartyResource) (result *extensions.ThirdPartyResource, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewCreateAction("thirdpartyresources", c.ns, thirdPartyResource), &extensions.ThirdPartyResource{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.ThirdPartyResource), err
|
||||
}
|
||||
|
||||
func (c *FakeThirdPartyResources) Update(thirdPartyResource *extensions.ThirdPartyResource) (result *extensions.ThirdPartyResource, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewUpdateAction("thirdpartyresources", c.ns, thirdPartyResource), &extensions.ThirdPartyResource{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.ThirdPartyResource), err
|
||||
}
|
||||
|
||||
func (c *FakeThirdPartyResources) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(core.NewDeleteAction("thirdpartyresources", c.ns, name), &extensions.ThirdPartyResource{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeThirdPartyResources) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := core.NewDeleteCollectionAction("thirdpartyresources", c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &extensions.ThirdPartyResourceList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeThirdPartyResources) Get(name string) (result *extensions.ThirdPartyResource, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewGetAction("thirdpartyresources", c.ns, name), &extensions.ThirdPartyResource{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.ThirdPartyResource), err
|
||||
}
|
||||
|
||||
func (c *FakeThirdPartyResources) List(opts api.ListOptions) (result *extensions.ThirdPartyResourceList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(core.NewListAction("thirdpartyresources", c.ns, opts), &extensions.ThirdPartyResourceList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &extensions.ThirdPartyResourceList{}
|
||||
for _, item := range obj.(*extensions.ThirdPartyResourceList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested thirdPartyResources.
|
||||
func (c *FakeThirdPartyResources) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(core.NewWatchAction("thirdpartyresources", c.ns, opts))
|
||||
|
||||
}
|
||||
29
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/generated_expansion.go
generated
vendored
Normal file
29
Godeps/_workspace/src/k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/generated_expansion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 unversioned
|
||||
|
||||
type DaemonSetExpansion interface{}
|
||||
|
||||
type HorizontalPodAutoscalerExpansion interface{}
|
||||
|
||||
type IngressExpansion interface{}
|
||||
|
||||
type JobExpansion interface{}
|
||||
|
||||
type ThirdPartyResourceExpansion interface{}
|
||||
|
||||
type ReplicaSetExpansion interface{}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue