vendor: bump k8s to v0.25.4

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2023-03-14 18:20:37 +01:00
parent 4a73abfd64
commit cfa6b4f7c8
889 changed files with 96934 additions and 11708 deletions

4
vendor/k8s.io/utils/clock/README.md generated vendored Normal file
View File

@ -0,0 +1,4 @@
# Clock
This package provides an interface for time-based operations. It allows
mocking time for testing.

178
vendor/k8s.io/utils/clock/clock.go generated vendored Normal file
View File

@ -0,0 +1,178 @@
/*
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 "time"
// PassiveClock allows for injecting fake or real clocks into code
// that needs to read the current time but does not support scheduling
// activity in the future.
type PassiveClock interface {
Now() time.Time
Since(time.Time) time.Duration
}
// Clock allows for injecting fake or real clocks into code that
// needs to do arbitrary things based on time.
type Clock interface {
PassiveClock
// After returns the channel of a new Timer.
// This method does not allow to free/GC the backing timer before it fires. Use
// NewTimer instead.
After(d time.Duration) <-chan time.Time
// NewTimer returns a new Timer.
NewTimer(d time.Duration) Timer
// Sleep sleeps for the provided duration d.
// Consider making the sleep interruptible by using 'select' on a context channel and a timer channel.
Sleep(d time.Duration)
// Tick returns the channel of a new Ticker.
// This method does not allow to free/GC the backing ticker. Use
// NewTicker from WithTicker instead.
Tick(d time.Duration) <-chan time.Time
}
// WithTicker allows for injecting fake or real clocks into code that
// needs to do arbitrary things based on time.
type WithTicker interface {
Clock
// NewTicker returns a new Ticker.
NewTicker(time.Duration) Ticker
}
// WithDelayedExecution allows for injecting fake or real clocks into
// code that needs to make use of AfterFunc functionality.
type WithDelayedExecution interface {
Clock
// AfterFunc executes f in its own goroutine after waiting
// for d duration and returns a Timer whose channel can be
// closed by calling Stop() on the Timer.
AfterFunc(d time.Duration, f func()) Timer
}
// WithTickerAndDelayedExecution allows for injecting fake or real clocks
// into code that needs Ticker and AfterFunc functionality
type WithTickerAndDelayedExecution interface {
WithTicker
// AfterFunc executes f in its own goroutine after waiting
// for d duration and returns a Timer whose channel can be
// closed by calling Stop() on the Timer.
AfterFunc(d time.Duration, f func()) Timer
}
// Ticker defines the Ticker interface.
type Ticker interface {
C() <-chan time.Time
Stop()
}
var _ = WithTicker(RealClock{})
// 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)
}
// After is the same as time.After(d).
// This method does not allow to free/GC the backing timer before it fires. Use
// NewTimer instead.
func (RealClock) After(d time.Duration) <-chan time.Time {
return time.After(d)
}
// NewTimer is the same as time.NewTimer(d)
func (RealClock) NewTimer(d time.Duration) Timer {
return &realTimer{
timer: time.NewTimer(d),
}
}
// AfterFunc is the same as time.AfterFunc(d, f).
func (RealClock) AfterFunc(d time.Duration, f func()) Timer {
return &realTimer{
timer: time.AfterFunc(d, f),
}
}
// Tick is the same as time.Tick(d)
// This method does not allow to free/GC the backing ticker. Use
// NewTicker instead.
func (RealClock) Tick(d time.Duration) <-chan time.Time {
return time.Tick(d)
}
// NewTicker returns a new Ticker.
func (RealClock) NewTicker(d time.Duration) Ticker {
return &realTicker{
ticker: time.NewTicker(d),
}
}
// Sleep is the same as time.Sleep(d)
// Consider making the sleep interruptible by using 'select' on a context channel and a timer channel.
func (RealClock) Sleep(d time.Duration) {
time.Sleep(d)
}
// 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{})
// 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)
}
type realTicker struct {
ticker *time.Ticker
}
func (r *realTicker) C() <-chan time.Time {
return r.ticker.C
}
func (r *realTicker) Stop() {
r.ticker.Stop()
}

361
vendor/k8s.io/utils/clock/testing/fake_clock.go generated vendored Normal file
View File

@ -0,0 +1,361 @@
/*
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 testing
import (
"sync"
"time"
"k8s.io/utils/clock"
)
var (
_ = clock.PassiveClock(&FakePassiveClock{})
_ = clock.WithTicker(&FakeClock{})
_ = clock.Clock(&IntervalClock{})
)
// FakePassiveClock implements PassiveClock, but returns an arbitrary time.
type FakePassiveClock struct {
lock sync.RWMutex
time time.Time
}
// FakeClock implements clock.Clock, but returns an arbitrary time.
type FakeClock struct {
FakePassiveClock
// 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
afterFunc func()
}
// NewFakePassiveClock returns a new FakePassiveClock.
func NewFakePassiveClock(t time.Time) *FakePassiveClock {
return &FakePassiveClock{
time: t,
}
}
// NewFakeClock constructs a fake clock set to the provided time.
func NewFakeClock(t time.Time) *FakeClock {
return &FakeClock{
FakePassiveClock: *NewFakePassiveClock(t),
}
}
// Now returns f's time.
func (f *FakePassiveClock) Now() time.Time {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time
}
// Since returns time since the time in f.
func (f *FakePassiveClock) Since(ts time.Time) time.Duration {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time.Sub(ts)
}
// SetTime sets the time on the FakePassiveClock.
func (f *FakePassiveClock) SetTime(t time.Time) {
f.lock.Lock()
defer f.lock.Unlock()
f.time = t
}
// 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()
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
}
// NewTimer constructs a fake timer, akin to time.NewTimer(d).
func (f *FakeClock) NewTimer(d time.Duration) clock.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
}
// AfterFunc is the Fake version of time.AfterFunc(d, cb).
func (f *FakeClock) AfterFunc(d time.Duration, cb func()) clock.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,
afterFunc: cb,
},
}
f.waiters = append(f.waiters, &timer.waiter)
return timer
}
// Tick constructs a fake ticker, akin to time.Tick
func (f *FakeClock) Tick(d time.Duration) <-chan time.Time {
if d <= 0 {
return nil
}
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
}
// NewTicker returns a new Ticker.
func (f *FakeClock) NewTicker(d time.Duration) clock.Ticker {
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 &fakeTicker{
c: ch,
}
}
// Step moves the clock by Duration and 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))
}
// SetTime 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.afterFunc != nil {
w.afterFunc()
}
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
}
// HasWaiters returns true if After or AfterFunc 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
}
// Sleep is akin to time.Sleep
func (f *FakeClock) Sleep(d time.Duration) {
f.Step(d)
}
// IntervalClock implements clock.PassiveClock, but each invocation of Now steps the clock forward the specified duration.
// IntervalClock technically implements the other methods of clock.Clock, but each implementation is just a panic.
//
// Deprecated: See SimpleIntervalClock for an alternative that only has the methods of PassiveClock.
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)
}
// After is 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")
}
// NewTimer is unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) NewTimer(d time.Duration) clock.Timer {
panic("IntervalClock doesn't implement NewTimer")
}
// AfterFunc is unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) AfterFunc(d time.Duration, f func()) clock.Timer {
panic("IntervalClock doesn't implement AfterFunc")
}
// Tick is 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")
}
// NewTicker has no implementation yet and is omitted.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) NewTicker(d time.Duration) clock.Ticker {
panic("IntervalClock doesn't implement NewTicker")
}
// Sleep is unimplemented, will panic.
func (*IntervalClock) Sleep(d time.Duration) {
panic("IntervalClock doesn't implement Sleep")
}
var _ = clock.Timer(&fakeTimer{})
// fakeTimer implements clock.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)
var isWaiting bool
for i := range f.fakeClock.waiters {
w := f.fakeClock.waiters[i]
if w == &f.waiter {
isWaiting = true
break
}
}
if !isWaiting {
f.fakeClock.waiters = append(f.fakeClock.waiters, &f.waiter)
}
return active
}
type fakeTicker struct {
c <-chan time.Time
}
func (t *fakeTicker) C() <-chan time.Time {
return t.c
}
func (t *fakeTicker) Stop() {
}

View File

@ -0,0 +1,44 @@
/*
Copyright 2021 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 testing
import (
"time"
"k8s.io/utils/clock"
)
var (
_ = clock.PassiveClock(&SimpleIntervalClock{})
)
// SimpleIntervalClock implements clock.PassiveClock, but each invocation of Now steps the clock forward the specified duration
type SimpleIntervalClock struct {
Time time.Time
Duration time.Duration
}
// Now returns i's time.
func (i *SimpleIntervalClock) Now() time.Time {
i.Time = i.Time.Add(i.Duration)
return i.Time
}
// Since returns time since the time in i.
func (i *SimpleIntervalClock) Since(ts time.Time) time.Duration {
return i.Time.Sub(ts)
}

View File

@ -0,0 +1,27 @@
Copyright (c) 2012 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View File

@ -0,0 +1,236 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// IP address manipulations
//
// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
// An IPv4 address can be converted to an IPv6 address by
// adding a canonical prefix (10 zeros, 2 0xFFs).
// This library accepts either size of byte slice but always
// returns 16-byte addresses.
package net
///////////////////////////////////////////////////////////////////////////////
// NOTE: This file was forked because we need to maintain backwards-compatible
// IP parsing logic, which was changed in a correct but incompatible way in
// go-1.17.
//
// See https://issue.k8s.io/100895
///////////////////////////////////////////////////////////////////////////////
import (
stdnet "net"
)
//
// Lean on the standard net lib as much as possible.
//
type IP = stdnet.IP
type IPNet = stdnet.IPNet
type ParseError = stdnet.ParseError
const IPv4len = stdnet.IPv4len
const IPv6len = stdnet.IPv6len
var CIDRMask = stdnet.CIDRMask
var IPv4 = stdnet.IPv4
// Parse IPv4 address (d.d.d.d).
func parseIPv4(s string) IP {
var p [IPv4len]byte
for i := 0; i < IPv4len; i++ {
if len(s) == 0 {
// Missing octets.
return nil
}
if i > 0 {
if s[0] != '.' {
return nil
}
s = s[1:]
}
n, c, ok := dtoi(s)
if !ok || n > 0xFF {
return nil
}
//
// NOTE: This correct check was added for go-1.17, but is a
// backwards-incompatible change for kubernetes users, who might have
// stored data which uses these leading zeroes already.
//
// See https://issue.k8s.io/100895
//
//if c > 1 && s[0] == '0' {
// // Reject non-zero components with leading zeroes.
// return nil
//}
s = s[c:]
p[i] = byte(n)
}
if len(s) != 0 {
return nil
}
return IPv4(p[0], p[1], p[2], p[3])
}
// parseIPv6 parses s as a literal IPv6 address described in RFC 4291
// and RFC 5952.
func parseIPv6(s string) (ip IP) {
ip = make(IP, IPv6len)
ellipsis := -1 // position of ellipsis in ip
// Might have leading ellipsis
if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
ellipsis = 0
s = s[2:]
// Might be only ellipsis
if len(s) == 0 {
return ip
}
}
// Loop, parsing hex numbers followed by colon.
i := 0
for i < IPv6len {
// Hex number.
n, c, ok := xtoi(s)
if !ok || n > 0xFFFF {
return nil
}
// If followed by dot, might be in trailing IPv4.
if c < len(s) && s[c] == '.' {
if ellipsis < 0 && i != IPv6len-IPv4len {
// Not the right place.
return nil
}
if i+IPv4len > IPv6len {
// Not enough room.
return nil
}
ip4 := parseIPv4(s)
if ip4 == nil {
return nil
}
ip[i] = ip4[12]
ip[i+1] = ip4[13]
ip[i+2] = ip4[14]
ip[i+3] = ip4[15]
s = ""
i += IPv4len
break
}
// Save this 16-bit chunk.
ip[i] = byte(n >> 8)
ip[i+1] = byte(n)
i += 2
// Stop at end of string.
s = s[c:]
if len(s) == 0 {
break
}
// Otherwise must be followed by colon and more.
if s[0] != ':' || len(s) == 1 {
return nil
}
s = s[1:]
// Look for ellipsis.
if s[0] == ':' {
if ellipsis >= 0 { // already have one
return nil
}
ellipsis = i
s = s[1:]
if len(s) == 0 { // can be at end
break
}
}
}
// Must have used entire string.
if len(s) != 0 {
return nil
}
// If didn't parse enough, expand ellipsis.
if i < IPv6len {
if ellipsis < 0 {
return nil
}
n := IPv6len - i
for j := i - 1; j >= ellipsis; j-- {
ip[j+n] = ip[j]
}
for j := ellipsis + n - 1; j >= ellipsis; j-- {
ip[j] = 0
}
} else if ellipsis >= 0 {
// Ellipsis must represent at least one 0 group.
return nil
}
return ip
}
// ParseIP parses s as an IP address, returning the result.
// The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
// ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
// If s is not a valid textual representation of an IP address,
// ParseIP returns nil.
func ParseIP(s string) IP {
for i := 0; i < len(s); i++ {
switch s[i] {
case '.':
return parseIPv4(s)
case ':':
return parseIPv6(s)
}
}
return nil
}
// ParseCIDR parses s as a CIDR notation IP address and prefix length,
// like "192.0.2.0/24" or "2001:db8::/32", as defined in
// RFC 4632 and RFC 4291.
//
// It returns the IP address and the network implied by the IP and
// prefix length.
// For example, ParseCIDR("192.0.2.1/24") returns the IP address
// 192.0.2.1 and the network 192.0.2.0/24.
func ParseCIDR(s string) (IP, *IPNet, error) {
i := indexByteString(s, '/')
if i < 0 {
return nil, nil, &ParseError{Type: "CIDR address", Text: s}
}
addr, mask := s[:i], s[i+1:]
iplen := IPv4len
ip := parseIPv4(addr)
if ip == nil {
iplen = IPv6len
ip = parseIPv6(addr)
}
n, i, ok := dtoi(mask)
if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
return nil, nil, &ParseError{Type: "CIDR address", Text: s}
}
m := CIDRMask(n, 8*iplen)
return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
}
// This is copied from go/src/internal/bytealg, which includes versions
// optimized for various platforms. Those optimizations are elided here so we
// don't have to maintain them.
func indexByteString(s string, c byte) int {
for i := 0; i < len(s); i++ {
if s[i] == c {
return i
}
}
return -1
}

View File

@ -0,0 +1,59 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Simple file i/o and string manipulation, to avoid
// depending on strconv and bufio and strings.
package net
///////////////////////////////////////////////////////////////////////////////
// NOTE: This file was forked because it is used by other code that needed to
// be forked, not because it is used on its own.
///////////////////////////////////////////////////////////////////////////////
// Bigger than we need, not too big to worry about overflow
const big = 0xFFFFFF
// Decimal to integer.
// Returns number, characters consumed, success.
func dtoi(s string) (n int, i int, ok bool) {
n = 0
for i = 0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
n = n*10 + int(s[i]-'0')
if n >= big {
return big, i, false
}
}
if i == 0 {
return 0, 0, false
}
return n, i, true
}
// Hexadecimal to integer.
// Returns number, characters consumed, success.
func xtoi(s string) (n int, i int, ok bool) {
n = 0
for i = 0; i < len(s); i++ {
if '0' <= s[i] && s[i] <= '9' {
n *= 16
n += int(s[i] - '0')
} else if 'a' <= s[i] && s[i] <= 'f' {
n *= 16
n += int(s[i]-'a') + 10
} else if 'A' <= s[i] && s[i] <= 'F' {
n *= 16
n += int(s[i]-'A') + 10
} else {
break
}
if n >= big {
return 0, i, false
}
}
if i == 0 {
return 0, i, false
}
return n, i, true
}

221
vendor/k8s.io/utils/net/ipnet.go generated vendored Normal file
View File

@ -0,0 +1,221 @@
/*
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 net
import (
"fmt"
"net"
"strings"
)
// IPNetSet maps string to net.IPNet.
type IPNetSet map[string]*net.IPNet
// ParseIPNets parses string slice to IPNetSet.
func ParseIPNets(specs ...string) (IPNetSet, error) {
ipnetset := make(IPNetSet)
for _, spec := range specs {
spec = strings.TrimSpace(spec)
_, ipnet, err := ParseCIDRSloppy(spec)
if err != nil {
return nil, err
}
k := ipnet.String() // In case of normalization
ipnetset[k] = ipnet
}
return ipnetset, nil
}
// Insert adds items to the set.
func (s IPNetSet) Insert(items ...*net.IPNet) {
for _, item := range items {
s[item.String()] = item
}
}
// Delete removes all items from the set.
func (s IPNetSet) Delete(items ...*net.IPNet) {
for _, item := range items {
delete(s, item.String())
}
}
// Has returns true if and only if item is contained in the set.
func (s IPNetSet) Has(item *net.IPNet) bool {
_, contained := s[item.String()]
return contained
}
// HasAll returns true if and only if all items are contained in the set.
func (s IPNetSet) HasAll(items ...*net.IPNet) bool {
for _, item := range items {
if !s.Has(item) {
return false
}
}
return true
}
// Difference returns a set of objects that are not in s2
// For example:
// s1 = {a1, a2, a3}
// s2 = {a1, a2, a4, a5}
// s1.Difference(s2) = {a3}
// s2.Difference(s1) = {a4, a5}
func (s IPNetSet) Difference(s2 IPNetSet) IPNetSet {
result := make(IPNetSet)
for k, i := range s {
_, found := s2[k]
if found {
continue
}
result[k] = i
}
return result
}
// StringSlice returns a []string with the String representation of each element in the set.
// Order is undefined.
func (s IPNetSet) StringSlice() []string {
a := make([]string, 0, len(s))
for k := range s {
a = append(a, k)
}
return a
}
// IsSuperset returns true if and only if s1 is a superset of s2.
func (s IPNetSet) IsSuperset(s2 IPNetSet) bool {
for k := range s2 {
_, found := s[k]
if !found {
return false
}
}
return true
}
// Equal returns true if and only if s1 is equal (as a set) to s2.
// Two sets are equal if their membership is identical.
// (In practice, this means same elements, order doesn't matter)
func (s IPNetSet) Equal(s2 IPNetSet) bool {
return len(s) == len(s2) && s.IsSuperset(s2)
}
// Len returns the size of the set.
func (s IPNetSet) Len() int {
return len(s)
}
// IPSet maps string to net.IP
type IPSet map[string]net.IP
// ParseIPSet parses string slice to IPSet
func ParseIPSet(items ...string) (IPSet, error) {
ipset := make(IPSet)
for _, item := range items {
ip := ParseIPSloppy(strings.TrimSpace(item))
if ip == nil {
return nil, fmt.Errorf("error parsing IP %q", item)
}
ipset[ip.String()] = ip
}
return ipset, nil
}
// Insert adds items to the set.
func (s IPSet) Insert(items ...net.IP) {
for _, item := range items {
s[item.String()] = item
}
}
// Delete removes all items from the set.
func (s IPSet) Delete(items ...net.IP) {
for _, item := range items {
delete(s, item.String())
}
}
// Has returns true if and only if item is contained in the set.
func (s IPSet) Has(item net.IP) bool {
_, contained := s[item.String()]
return contained
}
// HasAll returns true if and only if all items are contained in the set.
func (s IPSet) HasAll(items ...net.IP) bool {
for _, item := range items {
if !s.Has(item) {
return false
}
}
return true
}
// Difference returns a set of objects that are not in s2
// For example:
// s1 = {a1, a2, a3}
// s2 = {a1, a2, a4, a5}
// s1.Difference(s2) = {a3}
// s2.Difference(s1) = {a4, a5}
func (s IPSet) Difference(s2 IPSet) IPSet {
result := make(IPSet)
for k, i := range s {
_, found := s2[k]
if found {
continue
}
result[k] = i
}
return result
}
// StringSlice returns a []string with the String representation of each element in the set.
// Order is undefined.
func (s IPSet) StringSlice() []string {
a := make([]string, 0, len(s))
for k := range s {
a = append(a, k)
}
return a
}
// IsSuperset returns true if and only if s1 is a superset of s2.
func (s IPSet) IsSuperset(s2 IPSet) bool {
for k := range s2 {
_, found := s[k]
if !found {
return false
}
}
return true
}
// Equal returns true if and only if s1 is equal (as a set) to s2.
// Two sets are equal if their membership is identical.
// (In practice, this means same elements, order doesn't matter)
func (s IPSet) Equal(s2 IPSet) bool {
return len(s) == len(s2) && s.IsSuperset(s2)
}
// Len returns the size of the set.
func (s IPSet) Len() int {
return len(s)
}

213
vendor/k8s.io/utils/net/net.go generated vendored Normal file
View File

@ -0,0 +1,213 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package net
import (
"errors"
"fmt"
"math"
"math/big"
"net"
"strconv"
)
// ParseCIDRs parses a list of cidrs and return error if any is invalid.
// order is maintained
func ParseCIDRs(cidrsString []string) ([]*net.IPNet, error) {
cidrs := make([]*net.IPNet, 0, len(cidrsString))
for _, cidrString := range cidrsString {
_, cidr, err := ParseCIDRSloppy(cidrString)
if err != nil {
return nil, fmt.Errorf("failed to parse cidr value:%q with error:%v", cidrString, err)
}
cidrs = append(cidrs, cidr)
}
return cidrs, nil
}
// IsDualStackIPs returns if a slice of ips is:
// - all are valid ips
// - at least one ip from each family (v4 or v6)
func IsDualStackIPs(ips []net.IP) (bool, error) {
v4Found := false
v6Found := false
for _, ip := range ips {
if ip == nil {
return false, fmt.Errorf("ip %v is invalid", ip)
}
if v4Found && v6Found {
continue
}
if IsIPv6(ip) {
v6Found = true
continue
}
v4Found = true
}
return (v4Found && v6Found), nil
}
// IsDualStackIPStrings returns if
// - all are valid ips
// - at least one ip from each family (v4 or v6)
func IsDualStackIPStrings(ips []string) (bool, error) {
parsedIPs := make([]net.IP, 0, len(ips))
for _, ip := range ips {
parsedIP := ParseIPSloppy(ip)
parsedIPs = append(parsedIPs, parsedIP)
}
return IsDualStackIPs(parsedIPs)
}
// IsDualStackCIDRs returns if
// - all are valid cidrs
// - at least one cidr from each family (v4 or v6)
func IsDualStackCIDRs(cidrs []*net.IPNet) (bool, error) {
v4Found := false
v6Found := false
for _, cidr := range cidrs {
if cidr == nil {
return false, fmt.Errorf("cidr %v is invalid", cidr)
}
if v4Found && v6Found {
continue
}
if IsIPv6(cidr.IP) {
v6Found = true
continue
}
v4Found = true
}
return v4Found && v6Found, nil
}
// IsDualStackCIDRStrings returns if
// - all are valid cidrs
// - at least one cidr from each family (v4 or v6)
func IsDualStackCIDRStrings(cidrs []string) (bool, error) {
parsedCIDRs, err := ParseCIDRs(cidrs)
if err != nil {
return false, err
}
return IsDualStackCIDRs(parsedCIDRs)
}
// IsIPv6 returns if netIP is IPv6.
func IsIPv6(netIP net.IP) bool {
return netIP != nil && netIP.To4() == nil
}
// IsIPv6String returns if ip is IPv6.
func IsIPv6String(ip string) bool {
netIP := ParseIPSloppy(ip)
return IsIPv6(netIP)
}
// IsIPv6CIDRString returns if cidr is IPv6.
// This assumes cidr is a valid CIDR.
func IsIPv6CIDRString(cidr string) bool {
ip, _, _ := ParseCIDRSloppy(cidr)
return IsIPv6(ip)
}
// IsIPv6CIDR returns if a cidr is ipv6
func IsIPv6CIDR(cidr *net.IPNet) bool {
ip := cidr.IP
return IsIPv6(ip)
}
// IsIPv4 returns if netIP is IPv4.
func IsIPv4(netIP net.IP) bool {
return netIP != nil && netIP.To4() != nil
}
// IsIPv4String returns if ip is IPv4.
func IsIPv4String(ip string) bool {
netIP := ParseIPSloppy(ip)
return IsIPv4(netIP)
}
// IsIPv4CIDR returns if a cidr is ipv4
func IsIPv4CIDR(cidr *net.IPNet) bool {
ip := cidr.IP
return IsIPv4(ip)
}
// IsIPv4CIDRString returns if cidr is IPv4.
// This assumes cidr is a valid CIDR.
func IsIPv4CIDRString(cidr string) bool {
ip, _, _ := ParseCIDRSloppy(cidr)
return IsIPv4(ip)
}
// ParsePort parses a string representing an IP port. If the string is not a
// valid port number, this returns an error.
func ParsePort(port string, allowZero bool) (int, error) {
portInt, err := strconv.ParseUint(port, 10, 16)
if err != nil {
return 0, err
}
if portInt == 0 && !allowZero {
return 0, errors.New("0 is not a valid port number")
}
return int(portInt), nil
}
// BigForIP creates a big.Int based on the provided net.IP
func BigForIP(ip net.IP) *big.Int {
// NOTE: Convert to 16-byte representation so we can
// handle v4 and v6 values the same way.
return big.NewInt(0).SetBytes(ip.To16())
}
// AddIPOffset adds the provided integer offset to a base big.Int representing a net.IP
// NOTE: If you started with a v4 address and overflow it, you get a v6 result.
func AddIPOffset(base *big.Int, offset int) net.IP {
r := big.NewInt(0).Add(base, big.NewInt(int64(offset))).Bytes()
r = append(make([]byte, 16), r...)
return net.IP(r[len(r)-16:])
}
// RangeSize returns the size of a range in valid addresses.
// returns the size of the subnet (or math.MaxInt64 if the range size would overflow int64)
func RangeSize(subnet *net.IPNet) int64 {
ones, bits := subnet.Mask.Size()
if bits == 32 && (bits-ones) >= 31 || bits == 128 && (bits-ones) >= 127 {
return 0
}
// this checks that we are not overflowing an int64
if bits-ones >= 63 {
return math.MaxInt64
}
return int64(1) << uint(bits-ones)
}
// GetIndexedIP returns a net.IP that is subnet.IP + index in the contiguous IP space.
func GetIndexedIP(subnet *net.IPNet, index int) (net.IP, error) {
ip := AddIPOffset(BigForIP(subnet.IP), index)
if !subnet.Contains(ip) {
return nil, fmt.Errorf("can't generate IP with index %d from subnet. subnet too small. subnet: %q", index, subnet)
}
return ip, nil
}

33
vendor/k8s.io/utils/net/parse.go generated vendored Normal file
View File

@ -0,0 +1,33 @@
/*
Copyright 2021 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 net
import (
forkednet "k8s.io/utils/internal/third_party/forked/golang/net"
)
// ParseIPSloppy is identical to Go's standard net.ParseIP, except that it allows
// leading '0' characters on numbers. Go used to allow this and then changed
// the behavior in 1.17. We're choosing to keep it for compat with potential
// stored values.
var ParseIPSloppy = forkednet.ParseIP
// ParseCIDRSloppy is identical to Go's standard net.ParseCIDR, except that it allows
// leading '0' characters on numbers. Go used to allow this and then changed
// the behavior in 1.17. We're choosing to keep it for compat with potential
// stored values.
var ParseCIDRSloppy = forkednet.ParseCIDR

137
vendor/k8s.io/utils/net/port.go generated vendored Normal file
View File

@ -0,0 +1,137 @@
/*
Copyright 2020 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 net
import (
"fmt"
"net"
"strconv"
"strings"
)
// IPFamily refers to a specific family if not empty, i.e. "4" or "6".
type IPFamily string
// Constants for valid IPFamilys:
const (
IPv4 IPFamily = "4"
IPv6 IPFamily = "6"
)
// Protocol is a network protocol support by LocalPort.
type Protocol string
// Constants for valid protocols:
const (
TCP Protocol = "TCP"
UDP Protocol = "UDP"
)
// LocalPort represents an IP address and port pair along with a protocol
// and potentially a specific IP family.
// A LocalPort can be opened and subsequently closed.
type LocalPort struct {
// Description is an arbitrary string.
Description string
// IP is the IP address part of a given local port.
// If this string is empty, the port binds to all local IP addresses.
IP string
// If IPFamily is not empty, the port binds only to addresses of this
// family.
// IF empty along with IP, bind to local addresses of any family.
IPFamily IPFamily
// Port is the port number.
// A value of 0 causes a port to be automatically chosen.
Port int
// Protocol is the protocol, e.g. TCP
Protocol Protocol
}
// NewLocalPort returns a LocalPort instance and ensures IPFamily and IP are
// consistent and that the given protocol is valid.
func NewLocalPort(desc, ip string, ipFamily IPFamily, port int, protocol Protocol) (*LocalPort, error) {
if protocol != TCP && protocol != UDP {
return nil, fmt.Errorf("Unsupported protocol %s", protocol)
}
if ipFamily != "" && ipFamily != "4" && ipFamily != "6" {
return nil, fmt.Errorf("Invalid IP family %s", ipFamily)
}
if ip != "" {
parsedIP := ParseIPSloppy(ip)
if parsedIP == nil {
return nil, fmt.Errorf("invalid ip address %s", ip)
}
asIPv4 := parsedIP.To4()
if asIPv4 == nil && ipFamily == IPv4 || asIPv4 != nil && ipFamily == IPv6 {
return nil, fmt.Errorf("ip address and family mismatch %s, %s", ip, ipFamily)
}
}
return &LocalPort{Description: desc, IP: ip, IPFamily: ipFamily, Port: port, Protocol: protocol}, nil
}
func (lp *LocalPort) String() string {
ipPort := net.JoinHostPort(lp.IP, strconv.Itoa(lp.Port))
return fmt.Sprintf("%q (%s/%s%s)", lp.Description, ipPort, strings.ToLower(string(lp.Protocol)), lp.IPFamily)
}
// Closeable closes an opened LocalPort.
type Closeable interface {
Close() error
}
// PortOpener can open a LocalPort and allows later closing it.
type PortOpener interface {
OpenLocalPort(lp *LocalPort) (Closeable, error)
}
type listenPortOpener struct{}
// ListenPortOpener opens ports by calling bind() and listen().
var ListenPortOpener listenPortOpener
// OpenLocalPort holds the given local port open.
func (l *listenPortOpener) OpenLocalPort(lp *LocalPort) (Closeable, error) {
return openLocalPort(lp)
}
func openLocalPort(lp *LocalPort) (Closeable, error) {
var socket Closeable
hostPort := net.JoinHostPort(lp.IP, strconv.Itoa(lp.Port))
switch lp.Protocol {
case TCP:
network := "tcp" + string(lp.IPFamily)
listener, err := net.Listen(network, hostPort)
if err != nil {
return nil, err
}
socket = listener
case UDP:
network := "udp" + string(lp.IPFamily)
addr, err := net.ResolveUDPAddr(network, hostPort)
if err != nil {
return nil, err
}
conn, err := net.ListenUDP(network, addr)
if err != nil {
return nil, err
}
socket = conn
default:
return nil, fmt.Errorf("unknown protocol %q", lp.Protocol)
}
return socket, nil
}

82
vendor/k8s.io/utils/strings/slices/slices.go generated vendored Normal file
View File

@ -0,0 +1,82 @@
/*
Copyright 2021 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 slices defines various functions useful with slices of string type.
// The goal is to be as close as possible to
// https://github.com/golang/go/issues/45955. Ideal would be if we can just
// replace "stringslices" if the "slices" package becomes standard.
package slices
// Equal reports whether two slices are equal: the same length and all
// elements equal. If the lengths are different, Equal returns false.
// Otherwise, the elements are compared in index order, and the
// comparison stops at the first unequal pair.
func Equal(s1, s2 []string) bool {
if len(s1) != len(s2) {
return false
}
for i, n := range s1 {
if n != s2[i] {
return false
}
}
return true
}
// Filter appends to d each element e of s for which keep(e) returns true.
// It returns the modified d. d may be s[:0], in which case the kept
// elements will be stored in the same slice.
// if the slices overlap in some other way, the results are unspecified.
// To create a new slice with the filtered results, pass nil for d.
func Filter(d, s []string, keep func(string) bool) []string {
for _, n := range s {
if keep(n) {
d = append(d, n)
}
}
return d
}
// Contains reports whether v is present in s.
func Contains(s []string, v string) bool {
return Index(s, v) >= 0
}
// Index returns the index of the first occurrence of v in s, or -1 if
// not present.
func Index(s []string, v string) int {
// "Contains" may be replaced with "Index(s, v) >= 0":
// https://github.com/golang/go/issues/45955#issuecomment-873377947
for i, n := range s {
if n == v {
return i
}
}
return -1
}
// Functions below are not in https://github.com/golang/go/issues/45955
// Clone returns a new clone of s.
func Clone(s []string) []string {
// https://github.com/go101/go101/wiki/There-is-not-a-perfect-way-to-clone-slices-in-Go
if s == nil {
return nil
}
c := make([]string, len(s))
copy(c, s)
return c
}