Update go dependencies

This commit is contained in:
Manuel de Brito Fontes 2017-07-16 15:30:35 -04:00 committed by Minhan Xia
parent 060e449056
commit 4fb61c73d1
1192 changed files with 185874 additions and 302749 deletions

33
vendor/k8s.io/apimachinery/pkg/util/cache/BUILD generated vendored Normal file
View file

@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = [
"cache_test.go",
"lruexpirecache_test.go",
],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//vendor/github.com/golang/groupcache/lru:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/clock:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"cache.go",
"lruexpirecache.go",
],
tags = ["automanaged"],
deps = ["//vendor/github.com/hashicorp/golang-lru:go_default_library"],
)

83
vendor/k8s.io/apimachinery/pkg/util/cache/cache.go generated vendored Normal file
View file

@ -0,0 +1,83 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cache
import (
"sync"
)
const (
shardsCount int = 32
)
type Cache []*cacheShard
func NewCache(maxSize int) Cache {
if maxSize < shardsCount {
maxSize = shardsCount
}
cache := make(Cache, shardsCount)
for i := 0; i < shardsCount; i++ {
cache[i] = &cacheShard{
items: make(map[uint64]interface{}),
maxSize: maxSize / shardsCount,
}
}
return cache
}
func (c Cache) getShard(index uint64) *cacheShard {
return c[index%uint64(shardsCount)]
}
// Returns true if object already existed, false otherwise.
func (c *Cache) Add(index uint64, obj interface{}) bool {
return c.getShard(index).add(index, obj)
}
func (c *Cache) Get(index uint64) (obj interface{}, found bool) {
return c.getShard(index).get(index)
}
type cacheShard struct {
items map[uint64]interface{}
sync.RWMutex
maxSize int
}
// Returns true if object already existed, false otherwise.
func (s *cacheShard) add(index uint64, obj interface{}) bool {
s.Lock()
defer s.Unlock()
_, isOverwrite := s.items[index]
if !isOverwrite && len(s.items) >= s.maxSize {
var randomKey uint64
for randomKey = range s.items {
break
}
delete(s.items, randomKey)
}
s.items[index] = obj
return isOverwrite
}
func (s *cacheShard) get(index uint64) (obj interface{}, found bool) {
s.RLock()
defer s.RUnlock()
obj, found = s.items[index]
return
}

View file

@ -0,0 +1,102 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cache
import (
"sync"
"time"
"github.com/hashicorp/golang-lru"
)
// Clock defines an interface for obtaining the current time
type Clock interface {
Now() time.Time
}
// realClock implements the Clock interface by calling time.Now()
type realClock struct{}
func (realClock) Now() time.Time { return time.Now() }
// LRUExpireCache is a cache that ensures the mostly recently accessed keys are returned with
// a ttl beyond which keys are forcibly expired.
type LRUExpireCache struct {
// clock is used to obtain the current time
clock Clock
cache *lru.Cache
lock sync.Mutex
}
// NewLRUExpireCache creates an expiring cache with the given size
func NewLRUExpireCache(maxSize int) *LRUExpireCache {
return NewLRUExpireCacheWithClock(maxSize, realClock{})
}
// NewLRUExpireCacheWithClock creates an expiring cache with the given size, using the specified clock to obtain the current time.
func NewLRUExpireCacheWithClock(maxSize int, clock Clock) *LRUExpireCache {
cache, err := lru.New(maxSize)
if err != nil {
// if called with an invalid size
panic(err)
}
return &LRUExpireCache{clock: clock, cache: cache}
}
type cacheEntry struct {
value interface{}
expireTime time.Time
}
// Add adds the value to the cache at key with the specified maximum duration.
func (c *LRUExpireCache) Add(key interface{}, value interface{}, ttl time.Duration) {
c.lock.Lock()
defer c.lock.Unlock()
c.cache.Add(key, &cacheEntry{value, c.clock.Now().Add(ttl)})
}
// Get returns the value at the specified key from the cache if it exists and is not
// expired, or returns false.
func (c *LRUExpireCache) Get(key interface{}) (interface{}, bool) {
c.lock.Lock()
defer c.lock.Unlock()
e, ok := c.cache.Get(key)
if !ok {
return nil, false
}
if c.clock.Now().After(e.(*cacheEntry).expireTime) {
c.cache.Remove(key)
return nil, false
}
return e.(*cacheEntry).value, true
}
// Remove removes the specified key from the cache if it exists
func (c *LRUExpireCache) Remove(key interface{}) {
c.lock.Lock()
defer c.lock.Unlock()
c.cache.Remove(key)
}
// Keys returns all the keys in the cache, even if they are expired. Subsequent calls to
// get may return not found. It returns all keys from oldest to newest.
func (c *LRUExpireCache) Keys() []interface{} {
c.lock.Lock()
defer c.lock.Unlock()
return c.cache.Keys()
}

22
vendor/k8s.io/apimachinery/pkg/util/clock/BUILD generated vendored Normal file
View file

@ -0,0 +1,22 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["clock_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["clock.go"],
tags = ["automanaged"],
)

327
vendor/k8s.io/apimachinery/pkg/util/clock/clock.go generated vendored Normal file
View file

@ -0,0 +1,327 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clock
import (
"sync"
"time"
)
// Clock allows for injecting fake or real clocks into code that
// needs to do arbitrary things based on time.
type Clock interface {
Now() time.Time
Since(time.Time) time.Duration
After(d time.Duration) <-chan time.Time
NewTimer(d time.Duration) Timer
Sleep(d time.Duration)
Tick(d time.Duration) <-chan time.Time
}
var (
_ = Clock(RealClock{})
_ = Clock(&FakeClock{})
_ = Clock(&IntervalClock{})
)
// RealClock really calls time.Now()
type RealClock struct{}
// Now returns the current time.
func (RealClock) Now() time.Time {
return time.Now()
}
// Since returns time since the specified timestamp.
func (RealClock) Since(ts time.Time) time.Duration {
return time.Since(ts)
}
// Same as time.After(d).
func (RealClock) After(d time.Duration) <-chan time.Time {
return time.After(d)
}
func (RealClock) NewTimer(d time.Duration) Timer {
return &realTimer{
timer: time.NewTimer(d),
}
}
func (RealClock) Tick(d time.Duration) <-chan time.Time {
return time.Tick(d)
}
func (RealClock) Sleep(d time.Duration) {
time.Sleep(d)
}
// FakeClock implements Clock, but returns an arbitrary time.
type FakeClock struct {
lock sync.RWMutex
time time.Time
// waiters are waiting for the fake time to pass their specified time
waiters []fakeClockWaiter
}
type fakeClockWaiter struct {
targetTime time.Time
stepInterval time.Duration
skipIfBlocked bool
destChan chan time.Time
fired bool
}
func NewFakeClock(t time.Time) *FakeClock {
return &FakeClock{
time: t,
}
}
// Now returns f's time.
func (f *FakeClock) Now() time.Time {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time
}
// Since returns time since the time in f.
func (f *FakeClock) Since(ts time.Time) time.Duration {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time.Sub(ts)
}
// Fake version of time.After(d).
func (f *FakeClock) After(d time.Duration) <-chan time.Time {
f.lock.Lock()
defer f.lock.Unlock()
stopTime := f.time.Add(d)
ch := make(chan time.Time, 1) // Don't block!
f.waiters = append(f.waiters, fakeClockWaiter{
targetTime: stopTime,
destChan: ch,
})
return ch
}
// Fake version of time.NewTimer(d).
func (f *FakeClock) NewTimer(d time.Duration) Timer {
f.lock.Lock()
defer f.lock.Unlock()
stopTime := f.time.Add(d)
ch := make(chan time.Time, 1) // Don't block!
timer := &fakeTimer{
fakeClock: f,
waiter: fakeClockWaiter{
targetTime: stopTime,
destChan: ch,
},
}
f.waiters = append(f.waiters, timer.waiter)
return timer
}
func (f *FakeClock) Tick(d time.Duration) <-chan time.Time {
f.lock.Lock()
defer f.lock.Unlock()
tickTime := f.time.Add(d)
ch := make(chan time.Time, 1) // hold one tick
f.waiters = append(f.waiters, fakeClockWaiter{
targetTime: tickTime,
stepInterval: d,
skipIfBlocked: true,
destChan: ch,
})
return ch
}
// Move clock by Duration, notify anyone that's called After, Tick, or NewTimer
func (f *FakeClock) Step(d time.Duration) {
f.lock.Lock()
defer f.lock.Unlock()
f.setTimeLocked(f.time.Add(d))
}
// Sets the time.
func (f *FakeClock) SetTime(t time.Time) {
f.lock.Lock()
defer f.lock.Unlock()
f.setTimeLocked(t)
}
// Actually changes the time and checks any waiters. f must be write-locked.
func (f *FakeClock) setTimeLocked(t time.Time) {
f.time = t
newWaiters := make([]fakeClockWaiter, 0, len(f.waiters))
for i := range f.waiters {
w := &f.waiters[i]
if !w.targetTime.After(t) {
if w.skipIfBlocked {
select {
case w.destChan <- t:
w.fired = true
default:
}
} else {
w.destChan <- t
w.fired = true
}
if w.stepInterval > 0 {
for !w.targetTime.After(t) {
w.targetTime = w.targetTime.Add(w.stepInterval)
}
newWaiters = append(newWaiters, *w)
}
} else {
newWaiters = append(newWaiters, f.waiters[i])
}
}
f.waiters = newWaiters
}
// Returns true if After has been called on f but not yet satisfied (so you can
// write race-free tests).
func (f *FakeClock) HasWaiters() bool {
f.lock.RLock()
defer f.lock.RUnlock()
return len(f.waiters) > 0
}
func (f *FakeClock) Sleep(d time.Duration) {
f.Step(d)
}
// IntervalClock implements Clock, but each invocation of Now steps the clock forward the specified duration
type IntervalClock struct {
Time time.Time
Duration time.Duration
}
// Now returns i's time.
func (i *IntervalClock) Now() time.Time {
i.Time = i.Time.Add(i.Duration)
return i.Time
}
// Since returns time since the time in i.
func (i *IntervalClock) Since(ts time.Time) time.Duration {
return i.Time.Sub(ts)
}
// Unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) After(d time.Duration) <-chan time.Time {
panic("IntervalClock doesn't implement After")
}
// Unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) NewTimer(d time.Duration) Timer {
panic("IntervalClock doesn't implement NewTimer")
}
// Unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) Tick(d time.Duration) <-chan time.Time {
panic("IntervalClock doesn't implement Tick")
}
func (*IntervalClock) Sleep(d time.Duration) {
panic("IntervalClock doesn't implement Sleep")
}
// Timer allows for injecting fake or real timers into code that
// needs to do arbitrary things based on time.
type Timer interface {
C() <-chan time.Time
Stop() bool
Reset(d time.Duration) bool
}
var (
_ = Timer(&realTimer{})
_ = Timer(&fakeTimer{})
)
// realTimer is backed by an actual time.Timer.
type realTimer struct {
timer *time.Timer
}
// C returns the underlying timer's channel.
func (r *realTimer) C() <-chan time.Time {
return r.timer.C
}
// Stop calls Stop() on the underlying timer.
func (r *realTimer) Stop() bool {
return r.timer.Stop()
}
// Reset calls Reset() on the underlying timer.
func (r *realTimer) Reset(d time.Duration) bool {
return r.timer.Reset(d)
}
// fakeTimer implements Timer based on a FakeClock.
type fakeTimer struct {
fakeClock *FakeClock
waiter fakeClockWaiter
}
// C returns the channel that notifies when this timer has fired.
func (f *fakeTimer) C() <-chan time.Time {
return f.waiter.destChan
}
// Stop stops the timer and returns true if the timer has not yet fired, or false otherwise.
func (f *fakeTimer) Stop() bool {
f.fakeClock.lock.Lock()
defer f.fakeClock.lock.Unlock()
newWaiters := make([]fakeClockWaiter, 0, len(f.fakeClock.waiters))
for i := range f.fakeClock.waiters {
w := &f.fakeClock.waiters[i]
if w != &f.waiter {
newWaiters = append(newWaiters, *w)
}
}
f.fakeClock.waiters = newWaiters
return !f.waiter.fired
}
// Reset resets the timer to the fake clock's "now" + d. It returns true if the timer has not yet
// fired, or false otherwise.
func (f *fakeTimer) Reset(d time.Duration) bool {
f.fakeClock.lock.Lock()
defer f.fakeClock.lock.Unlock()
active := !f.waiter.fired
f.waiter.fired = false
f.waiter.targetTime = f.fakeClock.time.Add(d)
return active
}

View file

@ -21,6 +21,9 @@ import (
"fmt"
)
// MessageCountMap contains occurance for each error message.
type MessageCountMap map[string]int
// Aggregate represents an object that contains multiple errors, but does not
// necessarily have singular semantic meaning.
type Aggregate interface {
@ -147,6 +150,22 @@ func Flatten(agg Aggregate) Aggregate {
return NewAggregate(result)
}
// CreateAggregateFromMessageCountMap converts MessageCountMap Aggregate
func CreateAggregateFromMessageCountMap(m MessageCountMap) Aggregate {
if m == nil {
return nil
}
result := make([]error, 0, len(m))
for errStr, count := range m {
var countStr string
if count > 1 {
countStr = fmt.Sprintf(" (repeated %v times)", count)
}
result = append(result, fmt.Errorf("%v%v", errStr, countStr))
}
return NewAggregate(result)
}
// Reduce will return err or, if err is an Aggregate and only has one item,
// the first item in the aggregate.
func Reduce(err error) error {

View file

@ -358,23 +358,24 @@ func init() {
}
var fileDescriptorGenerated = []byte{
// 288 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8f, 0x31, 0x4b, 0xf4, 0x30,
0x1c, 0xc6, 0x93, 0xf7, 0xee, 0x3d, 0xb4, 0x82, 0x43, 0x71, 0x38, 0x1c, 0xd2, 0xa2, 0x20, 0x5d,
0x4c, 0x56, 0x71, 0xec, 0x76, 0x20, 0x08, 0x3d, 0x71, 0x70, 0x6b, 0xef, 0x62, 0x2e, 0xf4, 0x2e,
0x09, 0xe9, 0xbf, 0x42, 0xb7, 0xfb, 0x08, 0xba, 0x39, 0xfa, 0x71, 0x3a, 0xde, 0xe8, 0x20, 0x87,
0xad, 0xdf, 0xc2, 0x49, 0x9a, 0x16, 0x74, 0x4a, 0x9e, 0xe7, 0xf9, 0xfd, 0x02, 0xf1, 0x6e, 0xf2,
0xab, 0x82, 0x4a, 0xcd, 0xf2, 0x32, 0xe3, 0x56, 0x71, 0xe0, 0x05, 0x7b, 0xe2, 0x6a, 0xa9, 0x2d,
0x1b, 0x86, 0xd4, 0xc8, 0x4d, 0xba, 0x58, 0x49, 0xc5, 0x6d, 0xc5, 0x4c, 0x2e, 0x58, 0x09, 0x72,
0xcd, 0xa4, 0x82, 0x02, 0x2c, 0x13, 0x5c, 0x71, 0x9b, 0x02, 0x5f, 0x52, 0x63, 0x35, 0x68, 0xff,
0xbc, 0x97, 0xe8, 0x5f, 0x89, 0x9a, 0x5c, 0xd0, 0x4e, 0xa2, 0xbd, 0x74, 0x7a, 0x29, 0x24, 0xac,
0xca, 0x8c, 0x2e, 0xf4, 0x86, 0x09, 0x2d, 0x34, 0x73, 0x6e, 0x56, 0x3e, 0xba, 0xe4, 0x82, 0xbb,
0xf5, 0x6f, 0x9e, 0xbd, 0x60, 0xef, 0x68, 0xa6, 0xe0, 0xd6, 0xce, 0xc1, 0x4a, 0x25, 0xfc, 0xc8,
0x1b, 0x43, 0x65, 0xf8, 0x14, 0x87, 0x38, 0x1a, 0xc5, 0x27, 0xf5, 0x3e, 0x40, 0xed, 0x3e, 0x18,
0xdf, 0x55, 0x86, 0x7f, 0x0f, 0x67, 0xe2, 0x08, 0xff, 0xc2, 0x9b, 0x48, 0x05, 0xf7, 0xe9, 0x7a,
0xfa, 0x2f, 0xc4, 0xd1, 0xff, 0xf8, 0x78, 0x60, 0x27, 0x33, 0xd7, 0x26, 0xc3, 0xda, 0x71, 0x05,
0xd8, 0x8e, 0x1b, 0x85, 0x38, 0x3a, 0xfc, 0xe5, 0xe6, 0xae, 0x4d, 0x86, 0xf5, 0xfa, 0xe0, 0xf5,
0x2d, 0x40, 0xdb, 0x8f, 0x10, 0xc5, 0x51, 0xdd, 0x10, 0xb4, 0x6b, 0x08, 0x7a, 0x6f, 0x08, 0xda,
0xb6, 0x04, 0xd7, 0x2d, 0xc1, 0xbb, 0x96, 0xe0, 0xcf, 0x96, 0xe0, 0xe7, 0x2f, 0x82, 0x1e, 0x26,
0xfd, 0x67, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x55, 0xdf, 0x2a, 0x60, 0x01, 0x00, 0x00,
// 292 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8f, 0x31, 0x4b, 0x33, 0x31,
0x1c, 0xc6, 0x93, 0xb7, 0x7d, 0x8b, 0x9e, 0xe0, 0x50, 0x1c, 0x8a, 0x43, 0x7a, 0x28, 0xc8, 0x0d,
0x9a, 0xac, 0xe2, 0xd8, 0xad, 0x20, 0x08, 0x57, 0x71, 0x70, 0xbb, 0x6b, 0x63, 0x1a, 0xae, 0x4d,
0x42, 0xee, 0x7f, 0xc2, 0x6d, 0xfd, 0x08, 0xba, 0x39, 0xfa, 0x71, 0x6e, 0xec, 0xd8, 0x41, 0x8a,
0x17, 0xbf, 0x85, 0x93, 0x5c, 0xee, 0x40, 0xa7, 0xe4, 0x79, 0x9e, 0xdf, 0x2f, 0x90, 0xe0, 0x36,
0xbb, 0xce, 0xa9, 0xd4, 0x2c, 0x2b, 0x52, 0x6e, 0x15, 0x07, 0x9e, 0xb3, 0x67, 0xae, 0x16, 0xda,
0xb2, 0x6e, 0x48, 0x8c, 0x5c, 0x27, 0xf3, 0xa5, 0x54, 0xdc, 0x96, 0xcc, 0x64, 0x82, 0x15, 0x20,
0x57, 0x4c, 0x2a, 0xc8, 0xc1, 0x32, 0xc1, 0x15, 0xb7, 0x09, 0xf0, 0x05, 0x35, 0x56, 0x83, 0x1e,
0x9e, 0xb7, 0x12, 0xfd, 0x2b, 0x51, 0x93, 0x09, 0xda, 0x48, 0xb4, 0x95, 0x4e, 0xaf, 0x84, 0x84,
0x65, 0x91, 0xd2, 0xb9, 0x5e, 0x33, 0xa1, 0x85, 0x66, 0xde, 0x4d, 0x8b, 0x27, 0x9f, 0x7c, 0xf0,
0xb7, 0xf6, 0xcd, 0xb3, 0x57, 0x1c, 0x1c, 0x4d, 0x15, 0xdc, 0xd9, 0x19, 0x58, 0xa9, 0xc4, 0x30,
0x0a, 0xfa, 0x50, 0x1a, 0x3e, 0xc2, 0x21, 0x8e, 0x7a, 0x93, 0x93, 0x6a, 0x3f, 0x46, 0x6e, 0x3f,
0xee, 0xdf, 0x97, 0x86, 0x7f, 0x77, 0x67, 0xec, 0x89, 0xe1, 0x45, 0x30, 0x90, 0x0a, 0x1e, 0x92,
0xd5, 0xe8, 0x5f, 0x88, 0xa3, 0xff, 0x93, 0xe3, 0x8e, 0x1d, 0x4c, 0x7d, 0x1b, 0x77, 0x6b, 0xc3,
0xe5, 0x60, 0x1b, 0xae, 0x17, 0xe2, 0xe8, 0xf0, 0x97, 0x9b, 0xf9, 0x36, 0xee, 0xd6, 0x9b, 0x83,
0xb7, 0xf7, 0x31, 0xda, 0x7c, 0x84, 0x68, 0x72, 0x59, 0xd5, 0x04, 0x6d, 0x6b, 0x82, 0x76, 0x35,
0x41, 0x1b, 0x47, 0x70, 0xe5, 0x08, 0xde, 0x3a, 0x82, 0x77, 0x8e, 0xe0, 0x4f, 0x47, 0xf0, 0xcb,
0x17, 0x41, 0x8f, 0x83, 0xf6, 0xc3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x52, 0xa0, 0xb5, 0xc9,
0x64, 0x01, 0x00, 0x00,
}

View file

@ -0,0 +1,5 @@
approvers:
- pwittrock
reviewers:
- mengqiy
- apelisse

View file

@ -19,20 +19,41 @@ package mergepatch
import (
"errors"
"fmt"
"reflect"
)
var (
ErrBadJSONDoc = errors.New("Invalid JSON document")
ErrNoListOfLists = errors.New("Lists of lists are not supported")
ErrBadPatchFormatForPrimitiveList = errors.New("Invalid patch format of primitive list")
ErrBadJSONDoc = errors.New("invalid JSON document")
ErrNoListOfLists = errors.New("lists of lists are not supported")
ErrBadPatchFormatForPrimitiveList = errors.New("invalid patch format of primitive list")
ErrBadPatchFormatForRetainKeys = errors.New("invalid patch format of retainKeys")
ErrBadPatchFormatForSetElementOrderList = errors.New("invalid patch format of setElementOrder list")
ErrPatchContentNotMatchRetainKeys = errors.New("patch content doesn't match retainKeys list")
)
func ErrNoMergeKey(m map[string]interface{}, k string) error {
return fmt.Errorf("map: %v does not contain declared merge key: %s", m, k)
}
func ErrBadArgType(expected, actual string) error {
return fmt.Errorf("expected a %s, but received a %s", expected, actual)
func ErrBadArgType(expected, actual interface{}) error {
return fmt.Errorf("expected a %s, but received a %s",
reflect.TypeOf(expected),
reflect.TypeOf(actual))
}
func ErrBadArgKind(expected, actual interface{}) error {
var expectedKindString, actualKindString string
if expected == nil {
expectedKindString = "nil"
} else {
expectedKindString = reflect.TypeOf(expected).Kind().String()
}
if actual == nil {
actualKindString = "nil"
} else {
actualKindString = reflect.TypeOf(actual).Kind().String()
}
return fmt.Errorf("expected a %s, but received a %s", expectedKindString, actualKindString)
}
func ErrBadPatchType(t interface{}, m map[string]interface{}) error {

View file

@ -150,13 +150,13 @@ func GetHTTPClient(req *http.Request) string {
return "unknown"
}
// Extracts and returns the clients IP from the given request.
// Looks at X-Forwarded-For header, X-Real-Ip header and request.RemoteAddr in that order.
// Returns nil if none of them are set or is set to an invalid value.
func GetClientIP(req *http.Request) net.IP {
// SourceIPs splits the comma separated X-Forwarded-For header or returns the X-Real-Ip header or req.RemoteAddr,
// in that order, ignoring invalid IPs. It returns nil if all of these are empty or invalid.
func SourceIPs(req *http.Request) []net.IP {
hdr := req.Header
// First check the X-Forwarded-For header for requests via proxy.
hdrForwardedFor := hdr.Get("X-Forwarded-For")
forwardedForIPs := []net.IP{}
if hdrForwardedFor != "" {
// X-Forwarded-For can be a csv of IPs in case of multiple proxies.
// Use the first valid one.
@ -164,17 +164,20 @@ func GetClientIP(req *http.Request) net.IP {
for _, part := range parts {
ip := net.ParseIP(strings.TrimSpace(part))
if ip != nil {
return ip
forwardedForIPs = append(forwardedForIPs, ip)
}
}
}
if len(forwardedForIPs) > 0 {
return forwardedForIPs
}
// Try the X-Real-Ip header.
hdrRealIp := hdr.Get("X-Real-Ip")
if hdrRealIp != "" {
ip := net.ParseIP(hdrRealIp)
if ip != nil {
return ip
return []net.IP{ip}
}
}
@ -182,11 +185,43 @@ func GetClientIP(req *http.Request) net.IP {
// Remote Address in Go's HTTP server is in the form host:port so we need to split that first.
host, _, err := net.SplitHostPort(req.RemoteAddr)
if err == nil {
return net.ParseIP(host)
if remoteIP := net.ParseIP(host); remoteIP != nil {
return []net.IP{remoteIP}
}
}
// Fallback if Remote Address was just IP.
return net.ParseIP(req.RemoteAddr)
if remoteIP := net.ParseIP(req.RemoteAddr); remoteIP != nil {
return []net.IP{remoteIP}
}
return nil
}
// Extracts and returns the clients IP from the given request.
// Looks at X-Forwarded-For header, X-Real-Ip header and request.RemoteAddr in that order.
// Returns nil if none of them are set or is set to an invalid value.
func GetClientIP(req *http.Request) net.IP {
ips := SourceIPs(req)
if len(ips) == 0 {
return nil
}
return ips[0]
}
// Prepares the X-Forwarded-For header for another forwarding hop by appending the previous sender's
// IP address to the X-Forwarded-For chain.
func AppendForwardedForHeader(req *http.Request) {
// Copied from net/http/httputil/reverseproxy.go:
if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
// If we aren't the first proxy retain prior
// X-Forwarded-For information as a comma+space
// separated list and fold multiple headers into one.
if prior, ok := req.Header["X-Forwarded-For"]; ok {
clientIP = strings.Join(prior, ", ") + ", " + clientIP
}
req.Header.Set("X-Forwarded-For", clientIP)
}
}
var defaultProxyFuncPointer = fmt.Sprintf("%p", http.ProxyFromEnvironment)

View file

@ -29,6 +29,13 @@ import (
"github.com/golang/glog"
)
type AddressFamily uint
const (
familyIPv4 AddressFamily = 4
familyIPv6 AddressFamily = 6
)
type Route struct {
Interface string
Destination net.IP
@ -36,6 +43,7 @@ type Route struct {
// TODO: add more fields here if needed
}
// getRoutes obtains the IPv4 routes, and filters out non-default routes.
func getRoutes(input io.Reader) ([]Route, error) {
routes := []Route{}
if input == nil {
@ -52,24 +60,30 @@ func getRoutes(input io.Reader) ([]Route, error) {
continue
}
fields := strings.Fields(line)
routes = append(routes, Route{})
route := &routes[len(routes)-1]
route.Interface = fields[0]
ip, err := parseIP(fields[1])
dest, err := parseHexToIPv4(fields[1])
if err != nil {
return nil, err
}
route.Destination = ip
ip, err = parseIP(fields[2])
gw, err := parseHexToIPv4(fields[2])
if err != nil {
return nil, err
}
route.Gateway = ip
if !dest.Equal(net.IPv4zero) {
continue
}
routes = append(routes, Route{
Interface: fields[0],
Destination: dest,
Gateway: gw,
})
}
return routes, nil
}
func parseIP(str string) (net.IP, error) {
// parseHexToIPv4 takes the hex IP address string from route file and converts it
// from little endian to big endian for creation of a net.IP address.
// a net.IP, using big endian ordering.
func parseHexToIPv4(str string) (net.IP, error) {
if str == "" {
return nil, fmt.Errorf("input is nil")
}
@ -77,12 +91,10 @@ func parseIP(str string) (net.IP, error) {
if err != nil {
return nil, err
}
//TODO add ipv6 support
if len(bytes) != net.IPv4len {
return nil, fmt.Errorf("only IPv4 is supported")
return nil, fmt.Errorf("invalid IPv4 address in route")
}
bytes[0], bytes[1], bytes[2], bytes[3] = bytes[3], bytes[2], bytes[1], bytes[0]
return net.IP(bytes), nil
return net.IP([]byte{bytes[3], bytes[2], bytes[1], bytes[0]}), nil
}
func isInterfaceUp(intf *net.Interface) bool {
@ -96,10 +108,22 @@ func isInterfaceUp(intf *net.Interface) bool {
return false
}
//getFinalIP method receives all the IP addrs of a Interface
//and returns a nil if the address is Loopback, Ipv6, link-local or nil.
//It returns a valid IPv4 if an Ipv4 address is found in the array.
func getFinalIP(addrs []net.Addr) (net.IP, error) {
func isLoopbackOrPointToPoint(intf *net.Interface) bool {
return intf.Flags&(net.FlagLoopback|net.FlagPointToPoint) != 0
}
func inFamily(ip net.IP, expectedFamily AddressFamily) bool {
ipFamily := familyIPv4
if ip.To4() == nil {
ipFamily = familyIPv6
}
return ipFamily == expectedFamily
}
// getMatchingGlobalIP method checks all the IP addresses of a Interface looking
// for a valid non-loopback/link-local address of the requested family and returns
// it, if found.
func getMatchingGlobalIP(addrs []net.Addr, family AddressFamily) (net.IP, error) {
if len(addrs) > 0 {
for i := range addrs {
glog.V(4).Infof("Checking addr %s.", addrs[i].String())
@ -107,17 +131,15 @@ func getFinalIP(addrs []net.Addr) (net.IP, error) {
if err != nil {
return nil, err
}
//Only IPv4
//TODO : add IPv6 support
if ip.To4() != nil {
if !ip.IsLoopback() && !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
if inFamily(ip, family) {
if ip.IsGlobalUnicast() {
glog.V(4).Infof("IP found %v", ip)
return ip, nil
} else {
glog.V(4).Infof("Loopback/link-local found %v", ip)
glog.V(4).Infof("non-global IP found %v", ip)
}
} else {
glog.V(4).Infof("%v is not a valid IPv4 address", ip)
glog.V(4).Infof("%v is not an IPv%d address", ip, int(family))
}
}
@ -125,7 +147,7 @@ func getFinalIP(addrs []net.Addr) (net.IP, error) {
return nil, nil
}
func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
func getIPFromInterface(intfName string, forFamily AddressFamily, nw networkInterfacer) (net.IP, error) {
intf, err := nw.InterfaceByName(intfName)
if err != nil {
return nil, err
@ -136,63 +158,77 @@ func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
return nil, err
}
glog.V(4).Infof("Interface %q has %d addresses :%v.", intfName, len(addrs), addrs)
finalIP, err := getFinalIP(addrs)
matchingIP, err := getMatchingGlobalIP(addrs, forFamily)
if err != nil {
return nil, err
}
if finalIP != nil {
glog.V(4).Infof("valid IPv4 address for interface %q found as %v.", intfName, finalIP)
return finalIP, nil
if matchingIP != nil {
glog.V(4).Infof("Found valid IPv%d address %v for interface %q.", int(forFamily), matchingIP, intfName)
return matchingIP, nil
}
}
return nil, nil
}
func flagsSet(flags net.Flags, test net.Flags) bool {
return flags&test != 0
// memberOF tells if the IP is of the desired family. Used for checking interface addresses.
func memberOf(ip net.IP, family AddressFamily) bool {
if ip.To4() != nil {
return family == familyIPv4
} else {
return family == familyIPv6
}
}
func flagsClear(flags net.Flags, test net.Flags) bool {
return flags&test == 0
}
func chooseHostInterfaceNativeGo() (net.IP, error) {
intfs, err := net.Interfaces()
// chooseIPFromHostInterfaces looks at all system interfaces, trying to find one that is up that
// has a global unicast address (non-loopback, non-link local, non-point2point), and returns the IP.
// Searches for IPv4 addresses, and then IPv6 addresses.
func chooseIPFromHostInterfaces(nw networkInterfacer) (net.IP, error) {
intfs, err := nw.Interfaces()
if err != nil {
return nil, err
}
i := 0
var ip net.IP
for i = range intfs {
if flagsSet(intfs[i].Flags, net.FlagUp) && flagsClear(intfs[i].Flags, net.FlagLoopback|net.FlagPointToPoint) {
addrs, err := intfs[i].Addrs()
if len(intfs) == 0 {
return nil, fmt.Errorf("no interfaces found on host.")
}
for _, family := range []AddressFamily{familyIPv4, familyIPv6} {
glog.V(4).Infof("Looking for system interface with a global IPv%d address", uint(family))
for _, intf := range intfs {
if !isInterfaceUp(&intf) {
glog.V(4).Infof("Skipping: down interface %q", intf.Name)
continue
}
if isLoopbackOrPointToPoint(&intf) {
glog.V(4).Infof("Skipping: LB or P2P interface %q", intf.Name)
continue
}
addrs, err := nw.Addrs(&intf)
if err != nil {
return nil, err
}
if len(addrs) > 0 {
for _, addr := range addrs {
if addrIP, _, err := net.ParseCIDR(addr.String()); err == nil {
if addrIP.To4() != nil {
ip = addrIP.To4()
if !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
break
}
}
}
if len(addrs) == 0 {
glog.V(4).Infof("Skipping: no addresses on interface %q", intf.Name)
continue
}
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
if err != nil {
return nil, fmt.Errorf("Unable to parse CIDR for interface %q: %s", intf.Name, err)
}
if ip != nil {
// This interface should suffice.
break
if !memberOf(ip, family) {
glog.V(4).Infof("Skipping: no address family match for %q on interface %q.", ip, intf.Name)
continue
}
// TODO: Decide if should open up to allow IPv6 LLAs in future.
if !ip.IsGlobalUnicast() {
glog.V(4).Infof("Skipping: non-global address %q on interface %q.", ip, intf.Name)
continue
}
glog.V(4).Infof("Found global unicast address %q on interface %q.", ip, intf.Name)
return ip, nil
}
}
}
if ip == nil {
return nil, fmt.Errorf("no acceptable interface from host")
}
glog.V(4).Infof("Choosing interface %s (IP %v) as default", intfs[i].Name, ip)
return ip, nil
return nil, fmt.Errorf("no acceptable interface with global unicast address found on host")
}
//ChooseHostInterface is a method used fetch an IP for a daemon.
@ -200,39 +236,41 @@ func chooseHostInterfaceNativeGo() (net.IP, error) {
//For a node with no internet connection ,it returns error
//For a multi n/w interface node it returns the IP of the interface with gateway on it.
func ChooseHostInterface() (net.IP, error) {
var nw networkInterfacer = networkInterface{}
inFile, err := os.Open("/proc/net/route")
if err != nil {
if os.IsNotExist(err) {
return chooseHostInterfaceNativeGo()
return chooseIPFromHostInterfaces(nw)
}
return nil, err
}
defer inFile.Close()
var nw networkInterfacer = networkInterface{}
return chooseHostInterfaceFromRoute(inFile, nw)
}
// networkInterfacer defines an interface for several net library functions. Production
// code will forward to net library functions, and unit tests will override the methods
// for testing purposes.
type networkInterfacer interface {
InterfaceByName(intfName string) (*net.Interface, error)
Addrs(intf *net.Interface) ([]net.Addr, error)
Interfaces() ([]net.Interface, error)
}
// networkInterface implements the networkInterfacer interface for production code, just
// wrapping the underlying net library function calls.
type networkInterface struct{}
func (_ networkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
intf, err := net.InterfaceByName(intfName)
if err != nil {
return nil, err
}
return intf, nil
return net.InterfaceByName(intfName)
}
func (_ networkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
addrs, err := intf.Addrs()
if err != nil {
return nil, err
}
return addrs, nil
return intf.Addrs()
}
func (_ networkInterface) Interfaces() ([]net.Interface, error) {
return net.Interfaces()
}
func chooseHostInterfaceFromRoute(inFile io.Reader, nw networkInterfacer) (net.IP, error) {
@ -240,27 +278,30 @@ func chooseHostInterfaceFromRoute(inFile io.Reader, nw networkInterfacer) (net.I
if err != nil {
return nil, err
}
zero := net.IP{0, 0, 0, 0}
var finalIP net.IP
for i := range routes {
//find interface with gateway
if routes[i].Destination.Equal(zero) {
glog.V(4).Infof("Default route transits interface %q", routes[i].Interface)
finalIP, err := getIPFromInterface(routes[i].Interface, nw)
if len(routes) == 0 {
return nil, fmt.Errorf("No default routes.")
}
// TODO: append IPv6 routes for processing - currently only have IPv4 routes
for _, family := range []AddressFamily{familyIPv4, familyIPv6} {
glog.V(4).Infof("Looking for default routes with IPv%d addresses", uint(family))
for _, route := range routes {
// TODO: When have IPv6 routes, filter here to speed up processing
// if route.Family != family {
// continue
// }
glog.V(4).Infof("Default route transits interface %q", route.Interface)
finalIP, err := getIPFromInterface(route.Interface, family, nw)
if err != nil {
return nil, err
}
if finalIP != nil {
glog.V(4).Infof("Choosing IP %v ", finalIP)
glog.V(4).Infof("Found active IP %v ", finalIP)
return finalIP, nil
}
}
}
glog.V(4).Infof("No valid IP found")
if finalIP == nil {
return nil, fmt.Errorf("Unable to select an IP.")
}
return nil, nil
glog.V(4).Infof("No active IP found by looking at default routes")
return nil, fmt.Errorf("unable to select an IP from default routes.")
}
// If bind-address is usable, return it directly

View file

@ -2,19 +2,13 @@ package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load("@io_kubernetes_build//defs:go.bzl", "go_genrule")
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["set_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = [
@ -27,3 +21,38 @@ go_library(
],
tags = ["automanaged"],
)
go_genrule(
name = "set-gen",
srcs = [
"//hack/boilerplate:boilerplate.go.txt",
],
outs = [
"byte.go",
"doc.go",
"empty.go",
"int.go",
"int64.go",
"string.go",
],
cmd = """
$(location //cmd/libs/go2idl/set-gen) \
--input-dirs ./vendor/k8s.io/apimachinery/pkg/util/sets/types \
--output-base $(GENDIR)/vendor/k8s.io/apimachinery/pkg/util \
--go-header-file $(location //hack/boilerplate:boilerplate.go.txt) \
--output-package sets
""",
go_deps = [
"//vendor/k8s.io/apimachinery/pkg/util/sets/types:go_default_library",
],
tools = [
"//cmd/libs/go2idl/set-gen",
],
)
go_test(
name = "go_default_test",
srcs = ["set_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
)

View file

@ -0,0 +1,5 @@
approvers:
- pwittrock
reviewers:
- mengqiy
- apelisse

File diff suppressed because it is too large Load diff

View file

@ -13,12 +13,10 @@ go_test(
srcs = ["validation_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = ["//vendor/k8s.io/apimachinery/pkg/types:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["validation.go"],
tags = ["automanaged"],
deps = ["//vendor/k8s.io/apimachinery/pkg/types:go_default_library"],
)

View file

@ -22,8 +22,6 @@ import (
"net"
"regexp"
"strings"
"k8s.io/apimachinery/pkg/types"
)
const qnameCharFmt string = "[A-Za-z0-9]"
@ -200,7 +198,7 @@ const (
)
// IsValidGroupID tests that the argument is a valid Unix GID.
func IsValidGroupID(gid types.UnixGroupID) []string {
func IsValidGroupID(gid int64) []string {
if minGroupID <= gid && gid <= maxGroupID {
return nil
}
@ -208,7 +206,7 @@ func IsValidGroupID(gid types.UnixGroupID) []string {
}
// IsValidUserID tests that the argument is a valid Unix UID.
func IsValidUserID(uid types.UnixUserID) []string {
func IsValidUserID(uid int64) []string {
if minUserID <= uid && uid <= maxUserID {
return nil
}

View file

@ -65,9 +65,9 @@ func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) {
// JitterUntil loops until stop channel is closed, running f every period.
//
// If jitterFactor is positive, the period is jittered before every run of f.
// If jitterFactor is not positive, the period is unchanged and not jitterd.
// If jitterFactor is not positive, the period is unchanged and not jittered.
//
// If slidingis true, the period is computed after f runs. If it is false then
// If sliding is true, the period is computed after f runs. If it is false then
// period includes the runtime for f.
//
// Close stopCh to stop. f may not be invoked if stop channel is already
@ -138,14 +138,14 @@ type ConditionFunc func() (done bool, err error)
// Backoff holds parameters applied to a Backoff function.
type Backoff struct {
Duration time.Duration // the base duration
Factor float64 // Duration is multipled by factor each iteration
Factor float64 // Duration is multiplied by factor each iteration
Jitter float64 // The amount of jitter applied each iteration
Steps int // Exit with error after this many steps
}
// ExponentialBackoff repeats a condition check with exponential backoff.
//
// It checks the condition up to Steps times, increasing the wait by multipling
// It checks the condition up to Steps times, increasing the wait by multiplying
// the previous duration by Factor.
//
// If Jitter is greater than zero, a random amount of each duration is added