aboutsummaryrefslogtreecommitdiff
path: root/vendor/k8s.io/apimachinery/pkg/util
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/k8s.io/apimachinery/pkg/util')
-rw-r--r--vendor/k8s.io/apimachinery/pkg/util/clock/clock.go29
-rw-r--r--vendor/k8s.io/apimachinery/pkg/util/errors/errors.go32
-rw-r--r--vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go8
-rw-r--r--vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go60
-rw-r--r--vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go3
-rw-r--r--vendor/k8s.io/apimachinery/pkg/util/net/http.go55
-rw-r--r--vendor/k8s.io/apimachinery/pkg/util/validation/validation.go38
7 files changed, 142 insertions, 83 deletions
diff --git a/vendor/k8s.io/apimachinery/pkg/util/clock/clock.go b/vendor/k8s.io/apimachinery/pkg/util/clock/clock.go
index 1689e62e8..6cf13d83d 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/clock/clock.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/clock/clock.go
@@ -52,23 +52,26 @@ func (RealClock) Since(ts time.Time) time.Duration {
return time.Since(ts)
}
-// Same as time.After(d).
+// After is the same as time.After(d).
func (RealClock) After(d time.Duration) <-chan time.Time {
return time.After(d)
}
+// NewTimer returns a new Timer.
func (RealClock) NewTimer(d time.Duration) Timer {
return &realTimer{
timer: time.NewTimer(d),
}
}
+// NewTicker returns a new Ticker.
func (RealClock) NewTicker(d time.Duration) Ticker {
return &realTicker{
ticker: time.NewTicker(d),
}
}
+// Sleep pauses the RealClock for duration d.
func (RealClock) Sleep(d time.Duration) {
time.Sleep(d)
}
@@ -94,12 +97,14 @@ type fakeClockWaiter struct {
destChan chan time.Time
}
+// NewFakePassiveClock returns a new FakePassiveClock.
func NewFakePassiveClock(t time.Time) *FakePassiveClock {
return &FakePassiveClock{
time: t,
}
}
+// NewFakeClock returns a new FakeClock
func NewFakeClock(t time.Time) *FakeClock {
return &FakeClock{
FakePassiveClock: *NewFakePassiveClock(t),
@@ -120,14 +125,14 @@ func (f *FakePassiveClock) Since(ts time.Time) time.Duration {
return f.time.Sub(ts)
}
-// Sets the time.
+// SetTime sets the time on the FakePassiveClock.
func (f *FakePassiveClock) SetTime(t time.Time) {
f.lock.Lock()
defer f.lock.Unlock()
f.time = t
}
-// Fake version of time.After(d).
+// After is the Fake version of time.After(d).
func (f *FakeClock) After(d time.Duration) <-chan time.Time {
f.lock.Lock()
defer f.lock.Unlock()
@@ -140,7 +145,7 @@ func (f *FakeClock) After(d time.Duration) <-chan time.Time {
return ch
}
-// Fake version of time.NewTimer(d).
+// NewTimer is the Fake version of time.NewTimer(d).
func (f *FakeClock) NewTimer(d time.Duration) Timer {
f.lock.Lock()
defer f.lock.Unlock()
@@ -157,6 +162,7 @@ func (f *FakeClock) NewTimer(d time.Duration) Timer {
return timer
}
+// NewTicker returns a new Ticker.
func (f *FakeClock) NewTicker(d time.Duration) Ticker {
f.lock.Lock()
defer f.lock.Unlock()
@@ -174,14 +180,14 @@ func (f *FakeClock) NewTicker(d time.Duration) Ticker {
}
}
-// Move clock by Duration, notify anyone that's called After, Tick, or NewTimer
+// Step moves clock by Duration, notifies 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.
+// SetTime sets the time on a FakeClock.
func (f *FakeClock) SetTime(t time.Time) {
f.lock.Lock()
defer f.lock.Unlock()
@@ -219,7 +225,7 @@ func (f *FakeClock) setTimeLocked(t time.Time) {
f.waiters = newWaiters
}
-// Returns true if After has been called on f but not yet satisfied (so you can
+// HasWaiters 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()
@@ -227,6 +233,7 @@ func (f *FakeClock) HasWaiters() bool {
return len(f.waiters) > 0
}
+// Sleep pauses the FakeClock for duration d.
func (f *FakeClock) Sleep(d time.Duration) {
f.Step(d)
}
@@ -248,24 +255,25 @@ func (i *IntervalClock) Since(ts time.Time) time.Duration {
return i.Time.Sub(ts)
}
-// Unimplemented, will panic.
+// After is currently 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.
+// NewTimer is currently 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.
+// NewTicker is currently unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) NewTicker(d time.Duration) Ticker {
panic("IntervalClock doesn't implement NewTicker")
}
+// Sleep is currently unimplemented; will panic.
func (*IntervalClock) Sleep(d time.Duration) {
panic("IntervalClock doesn't implement Sleep")
}
@@ -355,6 +363,7 @@ func (f *fakeTimer) Reset(d time.Duration) bool {
return false
}
+// Ticker defines the Ticker interface
type Ticker interface {
C() <-chan time.Time
Stop()
diff --git a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
index 62a73f34e..5bafc218e 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
@@ -28,9 +28,14 @@ type MessageCountMap map[string]int
// Aggregate represents an object that contains multiple errors, but does not
// necessarily have singular semantic meaning.
+// The aggregate can be used with `errors.Is()` to check for the occurrence of
+// a specific error type.
+// Errors.As() is not supported, because the caller presumably cares about a
+// specific error of potentially multiple that match the given type.
type Aggregate interface {
error
Errors() []error
+ Is(error) bool
}
// NewAggregate converts a slice of errors into an Aggregate interface, which
@@ -71,16 +76,17 @@ func (agg aggregate) Error() string {
}
seenerrs := sets.NewString()
result := ""
- agg.visit(func(err error) {
+ agg.visit(func(err error) bool {
msg := err.Error()
if seenerrs.Has(msg) {
- return
+ return false
}
seenerrs.Insert(msg)
if len(seenerrs) > 1 {
result += ", "
}
result += msg
+ return false
})
if len(seenerrs) == 1 {
return result
@@ -88,19 +94,33 @@ func (agg aggregate) Error() string {
return "[" + result + "]"
}
-func (agg aggregate) visit(f func(err error)) {
+func (agg aggregate) Is(target error) bool {
+ return agg.visit(func(err error) bool {
+ return errors.Is(err, target)
+ })
+}
+
+func (agg aggregate) visit(f func(err error) bool) bool {
for _, err := range agg {
switch err := err.(type) {
case aggregate:
- err.visit(f)
+ if match := err.visit(f); match {
+ return match
+ }
case Aggregate:
for _, nestedErr := range err.Errors() {
- f(nestedErr)
+ if match := f(nestedErr); match {
+ return match
+ }
}
default:
- f(err)
+ if match := f(err); match {
+ return match
+ }
}
}
+
+ return false
}
// Errors is part of the Aggregate interface.
diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go
index 50d9a366f..9d5fdeece 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go
@@ -123,15 +123,11 @@ func negotiateProtocol(clientProtocols, serverProtocols []string) string {
func Handshake(req *http.Request, w http.ResponseWriter, serverProtocols []string) (string, error) {
clientProtocols := req.Header[http.CanonicalHeaderKey(HeaderProtocolVersion)]
if len(clientProtocols) == 0 {
- // Kube 1.0 clients didn't support subprotocol negotiation.
- // TODO require clientProtocols once Kube 1.0 is no longer supported
- return "", nil
+ return "", fmt.Errorf("unable to upgrade: %s is required", HeaderProtocolVersion)
}
if len(serverProtocols) == 0 {
- // Kube 1.0 servers didn't support subprotocol negotiation. This is mainly for testing.
- // TODO require serverProtocols once Kube 1.0 is no longer supported
- return "", nil
+ panic(fmt.Errorf("unable to upgrade: serverProtocols is required"))
}
negotiatedProtocol := negotiateProtocol(clientProtocols, serverProtocols)
diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
index 64cbc7703..ec1cb70f2 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go
@@ -38,7 +38,7 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func (m *IntOrString) Reset() { *m = IntOrString{} }
func (*IntOrString) ProtoMessage() {}
@@ -289,6 +289,7 @@ func (m *IntOrString) Unmarshal(dAtA []byte) error {
func skipGenerated(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
+ depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
@@ -320,10 +321,8 @@ func skipGenerated(dAtA []byte) (n int, err error) {
break
}
}
- return iNdEx, nil
case 1:
iNdEx += 8
- return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
@@ -344,55 +343,30 @@ func skipGenerated(dAtA []byte) (n int, err error) {
return 0, ErrInvalidLengthGenerated
}
iNdEx += length
- if iNdEx < 0 {
- return 0, ErrInvalidLengthGenerated
- }
- return iNdEx, nil
case 3:
- for {
- var innerWire uint64
- var start int = iNdEx
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return 0, ErrIntOverflowGenerated
- }
- if iNdEx >= l {
- return 0, io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- innerWire |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- innerWireType := int(innerWire & 0x7)
- if innerWireType == 4 {
- break
- }
- next, err := skipGenerated(dAtA[start:])
- if err != nil {
- return 0, err
- }
- iNdEx = start + next
- if iNdEx < 0 {
- return 0, ErrInvalidLengthGenerated
- }
- }
- return iNdEx, nil
+ depth++
case 4:
- return iNdEx, nil
+ if depth == 0 {
+ return 0, ErrUnexpectedEndOfGroupGenerated
+ }
+ depth--
case 5:
iNdEx += 4
- return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
+ if iNdEx < 0 {
+ return 0, ErrInvalidLengthGenerated
+ }
+ if depth == 0 {
+ return iNdEx, nil
+ }
}
- panic("unreachable")
+ return 0, io.ErrUnexpectedEOF
}
var (
- ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
- ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
+ ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
+ ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group")
)
diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
index 2df629555..cb974dcf7 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
@@ -97,7 +97,8 @@ func (intstr *IntOrString) String() string {
}
// IntValue returns the IntVal if type Int, or if
-// it is a String, will attempt a conversion to int.
+// it is a String, will attempt a conversion to int,
+// returning 0 if a parsing error occurs.
func (intstr *IntOrString) IntValue() int {
if intstr.Type == String {
i, _ := strconv.Atoi(intstr.StrVal)
diff --git a/vendor/k8s.io/apimachinery/pkg/util/net/http.go b/vendor/k8s.io/apimachinery/pkg/util/net/http.go
index f9540c63b..7449cbb0a 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/net/http.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/net/http.go
@@ -55,6 +55,12 @@ func JoinPreservingTrailingSlash(elem ...string) string {
return result
}
+// IsTimeout returns true if the given error is a network timeout error
+func IsTimeout(err error) bool {
+ neterr, ok := err.(net.Error)
+ return ok && neterr != nil && neterr.Timeout()
+}
+
// IsProbableEOF returns true if the given error resembles a connection termination
// scenario that would justify assuming that the watch is empty.
// These errors are what the Go http stack returns back to us which are general
@@ -206,13 +212,17 @@ func GetHTTPClient(req *http.Request) string {
return "unknown"
}
-// 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.
+// SourceIPs splits the comma separated X-Forwarded-For header and joins it with
+// the X-Real-Ip header and/or req.RemoteAddr, ignoring invalid IPs.
+// The X-Real-Ip is omitted if it's already present in the X-Forwarded-For chain.
+// The req.RemoteAddr is always the last IP in the returned list.
+// It returns nil if all of these are empty or invalid.
func SourceIPs(req *http.Request) []net.IP {
+ var srcIPs []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.
@@ -220,38 +230,49 @@ func SourceIPs(req *http.Request) []net.IP {
for _, part := range parts {
ip := net.ParseIP(strings.TrimSpace(part))
if ip != nil {
- forwardedForIPs = append(forwardedForIPs, ip)
+ srcIPs = append(srcIPs, 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 []net.IP{ip}
+ // Only append the X-Real-Ip if it's not already contained in the X-Forwarded-For chain.
+ if ip != nil && !containsIP(srcIPs, ip) {
+ srcIPs = append(srcIPs, ip)
}
}
- // Fallback to Remote Address in request, which will give the correct client IP when there is no proxy.
+ // Always include the request Remote Address as it cannot be easily spoofed.
+ var remoteIP 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 {
- if remoteIP := net.ParseIP(host); remoteIP != nil {
- return []net.IP{remoteIP}
- }
+ remoteIP = net.ParseIP(host)
}
-
// Fallback if Remote Address was just IP.
- if remoteIP := net.ParseIP(req.RemoteAddr); remoteIP != nil {
- return []net.IP{remoteIP}
+ if remoteIP == nil {
+ remoteIP = net.ParseIP(req.RemoteAddr)
+ }
+
+ // Don't duplicate remote IP if it's already the last address in the chain.
+ if remoteIP != nil && (len(srcIPs) == 0 || !remoteIP.Equal(srcIPs[len(srcIPs)-1])) {
+ srcIPs = append(srcIPs, remoteIP)
}
- return nil
+ return srcIPs
+}
+
+// Checks whether the given IP address is contained in the list of IPs.
+func containsIP(ips []net.IP, ip net.IP) bool {
+ for _, v := range ips {
+ if v.Equal(ip) {
+ return true
+ }
+ }
+ return false
}
// Extracts and returns the clients IP from the given request.
diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
index 8e1907c2a..915231f2e 100644
--- a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
+++ b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
@@ -109,6 +109,44 @@ func IsFullyQualifiedDomainName(fldPath *field.Path, name string) field.ErrorLis
return allErrors
}
+// Allowed characters in an HTTP Path as defined by RFC 3986. A HTTP path may
+// contain:
+// * unreserved characters (alphanumeric, '-', '.', '_', '~')
+// * percent-encoded octets
+// * sub-delims ("!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=")
+// * a colon character (":")
+const httpPathFmt string = `[A-Za-z0-9/\-._~%!$&'()*+,;=:]+`
+
+var httpPathRegexp = regexp.MustCompile("^" + httpPathFmt + "$")
+
+// IsDomainPrefixedPath checks if the given string is a domain-prefixed path
+// (e.g. acme.io/foo). All characters before the first "/" must be a valid
+// subdomain as defined by RFC 1123. All characters trailing the first "/" must
+// be valid HTTP Path characters as defined by RFC 3986.
+func IsDomainPrefixedPath(fldPath *field.Path, dpPath string) field.ErrorList {
+ var allErrs field.ErrorList
+ if len(dpPath) == 0 {
+ return append(allErrs, field.Required(fldPath, ""))
+ }
+
+ segments := strings.SplitN(dpPath, "/", 2)
+ if len(segments) != 2 || len(segments[0]) == 0 || len(segments[1]) == 0 {
+ return append(allErrs, field.Invalid(fldPath, dpPath, "must be a domain-prefixed path (such as \"acme.io/foo\")"))
+ }
+
+ host := segments[0]
+ for _, err := range IsDNS1123Subdomain(host) {
+ allErrs = append(allErrs, field.Invalid(fldPath, host, err))
+ }
+
+ path := segments[1]
+ if !httpPathRegexp.MatchString(path) {
+ return append(allErrs, field.Invalid(fldPath, path, RegexError("Invalid path", httpPathFmt)))
+ }
+
+ return allErrs
+}
+
const labelValueFmt string = "(" + qualifiedNameFmt + ")?"
const labelValueErrMsg string = "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character"