*: initial update to kube 1.8
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
2453222695
commit
d6e819133d
1237 changed files with 84117 additions and 564982 deletions
2
vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
generated
vendored
2
vendor/k8s.io/apimachinery/pkg/util/errors/errors.go
generated
vendored
|
@ -21,7 +21,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// MessagesgCountMap contains occurance for each error message.
|
||||
// MessageCountMap contains occurance for each error message.
|
||||
type MessageCountMap map[string]int
|
||||
|
||||
// Aggregate represents an object that contains multiple errors, but does not
|
||||
|
|
2
vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
generated
vendored
2
vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go
generated
vendored
|
@ -24,7 +24,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/openapi"
|
||||
openapi "k8s.io/kube-openapi/pkg/common"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/golang/glog"
|
||||
|
|
12
vendor/k8s.io/apimachinery/pkg/util/json/json.go
generated
vendored
12
vendor/k8s.io/apimachinery/pkg/util/json/json.go
generated
vendored
|
@ -50,6 +50,18 @@ func Unmarshal(data []byte, v interface{}) error {
|
|||
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
|
||||
return convertMapNumbers(*v)
|
||||
|
||||
case *[]interface{}:
|
||||
// Build a decoder from the given data
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(data))
|
||||
// Preserve numbers, rather than casting to float64 automatically
|
||||
decoder.UseNumber()
|
||||
// Run the decode
|
||||
if err := decoder.Decode(v); err != nil {
|
||||
return err
|
||||
}
|
||||
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
|
||||
return convertSliceNumbers(*v)
|
||||
|
||||
default:
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
|
|
11
vendor/k8s.io/apimachinery/pkg/util/net/http.go
generated
vendored
11
vendor/k8s.io/apimachinery/pkg/util/net/http.go
generated
vendored
|
@ -108,7 +108,7 @@ func DialerFor(transport http.RoundTripper) (DialFunc, error) {
|
|||
case RoundTripperWrapper:
|
||||
return DialerFor(transport.WrappedRoundTripper())
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown transport type: %v", transport)
|
||||
return nil, fmt.Errorf("unknown transport type: %T", transport)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ func TLSClientConfig(transport http.RoundTripper) (*tls.Config, error) {
|
|||
case RoundTripperWrapper:
|
||||
return TLSClientConfig(transport.WrappedRoundTripper())
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown transport type: %v", transport)
|
||||
return nil, fmt.Errorf("unknown transport type: %T", transport)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,6 +277,13 @@ func NewProxierWithNoProxyCIDR(delegate func(req *http.Request) (*url.URL, error
|
|||
}
|
||||
}
|
||||
|
||||
// DialerFunc implements Dialer for the provided function.
|
||||
type DialerFunc func(req *http.Request) (net.Conn, error)
|
||||
|
||||
func (fn DialerFunc) Dial(req *http.Request) (net.Conn, error) {
|
||||
return fn(req)
|
||||
}
|
||||
|
||||
// Dialer dials a host and writes a request to it.
|
||||
type Dialer interface {
|
||||
// Dial connects to the host specified by req's URL, writes the request to the connection, and
|
||||
|
|
314
vendor/k8s.io/apimachinery/pkg/util/net/interface.go
generated
vendored
314
vendor/k8s.io/apimachinery/pkg/util/net/interface.go
generated
vendored
|
@ -29,18 +29,47 @@ import (
|
|||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type AddressFamily uint
|
||||
|
||||
const (
|
||||
familyIPv4 AddressFamily = 4
|
||||
familyIPv6 AddressFamily = 6
|
||||
)
|
||||
|
||||
const (
|
||||
ipv4RouteFile = "/proc/net/route"
|
||||
ipv6RouteFile = "/proc/net/ipv6_route"
|
||||
)
|
||||
|
||||
type Route struct {
|
||||
Interface string
|
||||
Destination net.IP
|
||||
Gateway net.IP
|
||||
// TODO: add more fields here if needed
|
||||
Family AddressFamily
|
||||
}
|
||||
|
||||
func getRoutes(input io.Reader) ([]Route, error) {
|
||||
routes := []Route{}
|
||||
if input == nil {
|
||||
return nil, fmt.Errorf("input is nil")
|
||||
type RouteFile struct {
|
||||
name string
|
||||
parse func(input io.Reader) ([]Route, error)
|
||||
}
|
||||
|
||||
var (
|
||||
v4File = RouteFile{name: ipv4RouteFile, parse: getIPv4DefaultRoutes}
|
||||
v6File = RouteFile{name: ipv6RouteFile, parse: getIPv6DefaultRoutes}
|
||||
)
|
||||
|
||||
func (rf RouteFile) extract() ([]Route, error) {
|
||||
file, err := os.Open(rf.name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
return rf.parse(file)
|
||||
}
|
||||
|
||||
// getIPv4DefaultRoutes obtains the IPv4 routes, and filters out non-default routes.
|
||||
func getIPv4DefaultRoutes(input io.Reader) ([]Route, error) {
|
||||
routes := []Route{}
|
||||
scanner := bufio.NewReader(input)
|
||||
for {
|
||||
line, err := scanner.ReadString('\n')
|
||||
|
@ -52,24 +81,71 @@ 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])
|
||||
// Interested in fields:
|
||||
// 0 - interface name
|
||||
// 1 - destination address
|
||||
// 2 - gateway
|
||||
dest, err := parseIP(fields[1], familyIPv4)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
route.Destination = ip
|
||||
ip, err = parseIP(fields[2])
|
||||
gw, err := parseIP(fields[2], familyIPv4)
|
||||
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,
|
||||
Family: familyIPv4,
|
||||
})
|
||||
}
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
func parseIP(str string) (net.IP, error) {
|
||||
func getIPv6DefaultRoutes(input io.Reader) ([]Route, error) {
|
||||
routes := []Route{}
|
||||
scanner := bufio.NewReader(input)
|
||||
for {
|
||||
line, err := scanner.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
fields := strings.Fields(line)
|
||||
// Interested in fields:
|
||||
// 0 - destination address
|
||||
// 4 - gateway
|
||||
// 9 - interface name
|
||||
dest, err := parseIP(fields[0], familyIPv6)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gw, err := parseIP(fields[4], familyIPv6)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !dest.Equal(net.IPv6zero) {
|
||||
continue
|
||||
}
|
||||
if gw.Equal(net.IPv6zero) {
|
||||
continue // loopback
|
||||
}
|
||||
routes = append(routes, Route{
|
||||
Interface: fields[9],
|
||||
Destination: dest,
|
||||
Gateway: gw,
|
||||
Family: familyIPv6,
|
||||
})
|
||||
}
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
// parseIP takes the hex IP address string from route file and converts it
|
||||
// to a net.IP address. For IPv4, the value must be converted to big endian.
|
||||
func parseIP(str string, family AddressFamily) (net.IP, error) {
|
||||
if str == "" {
|
||||
return nil, fmt.Errorf("input is nil")
|
||||
}
|
||||
|
@ -77,11 +153,16 @@ 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")
|
||||
if family == familyIPv4 {
|
||||
if len(bytes) != net.IPv4len {
|
||||
return nil, fmt.Errorf("invalid IPv4 address in route")
|
||||
}
|
||||
return net.IP([]byte{bytes[3], bytes[2], bytes[1], bytes[0]}), nil
|
||||
}
|
||||
// Must be IPv6
|
||||
if len(bytes) != net.IPv6len {
|
||||
return nil, fmt.Errorf("invalid IPv6 address in route")
|
||||
}
|
||||
bytes[0], bytes[1], bytes[2], bytes[3] = bytes[3], bytes[2], bytes[1], bytes[0]
|
||||
return net.IP(bytes), nil
|
||||
}
|
||||
|
||||
|
@ -96,10 +177,13 @@ 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
|
||||
}
|
||||
|
||||
// getMatchingGlobalIP returns the first valid global unicast address of the given
|
||||
// 'family' from the list of 'addrs'.
|
||||
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 +191,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 memberOf(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 unicast address 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 +207,9 @@ func getFinalIP(addrs []net.Addr) (net.IP, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
|
||||
// getIPFromInterface gets the IPs on an interface and returns a global unicast address, if any. The
|
||||
// interface must be up, the IP must in the family requested, and the IP must be a global unicast address.
|
||||
func getIPFromInterface(intfName string, forFamily AddressFamily, nw networkInterfacer) (net.IP, error) {
|
||||
intf, err := nw.InterfaceByName(intfName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -136,131 +220,161 @@ 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.
|
||||
//It uses data from /proc/net/route file.
|
||||
//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.
|
||||
// ChooseHostInterface is a method used fetch an IP for a daemon.
|
||||
// If there is no routing info file, it will choose a global IP from the system
|
||||
// interfaces. Otherwise, it will use IPv4 and IPv6 route information to return the
|
||||
// IP of the interface with a gateway on it (with priority given to IPv4). For a node
|
||||
// with no internet connection, it returns error.
|
||||
func ChooseHostInterface() (net.IP, error) {
|
||||
inFile, err := os.Open("/proc/net/route")
|
||||
var nw networkInterfacer = networkInterface{}
|
||||
if _, err := os.Stat(ipv4RouteFile); os.IsNotExist(err) {
|
||||
return chooseIPFromHostInterfaces(nw)
|
||||
}
|
||||
routes, err := getAllDefaultRoutes()
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return chooseHostInterfaceNativeGo()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer inFile.Close()
|
||||
var nw networkInterfacer = networkInterface{}
|
||||
return chooseHostInterfaceFromRoute(inFile, nw)
|
||||
return chooseHostInterfaceFromRoute(routes, 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 chooseHostInterfaceFromRoute(inFile io.Reader, nw networkInterfacer) (net.IP, error) {
|
||||
routes, err := getRoutes(inFile)
|
||||
func (_ networkInterface) Interfaces() ([]net.Interface, error) {
|
||||
return net.Interfaces()
|
||||
}
|
||||
|
||||
// getAllDefaultRoutes obtains IPv4 and IPv6 default routes on the node. If unable
|
||||
// to read the IPv4 routing info file, we return an error. If unable to read the IPv6
|
||||
// routing info file (which is optional), we'll just use the IPv4 route information.
|
||||
// Using all the routing info, if no default routes are found, an error is returned.
|
||||
func getAllDefaultRoutes() ([]Route, error) {
|
||||
routes, err := v4File.extract()
|
||||
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)
|
||||
v6Routes, _ := v6File.extract()
|
||||
routes = append(routes, v6Routes...)
|
||||
if len(routes) == 0 {
|
||||
return nil, fmt.Errorf("No default routes.")
|
||||
}
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
// chooseHostInterfaceFromRoute cycles through each default route provided, looking for a
|
||||
// global IP address from the interface for the route. Will first look all each IPv4 route for
|
||||
// an IPv4 IP, and then will look at each IPv6 route for an IPv6 IP.
|
||||
func chooseHostInterfaceFromRoute(routes []Route, nw networkInterfacer) (net.IP, error) {
|
||||
for _, family := range []AddressFamily{familyIPv4, familyIPv6} {
|
||||
glog.V(4).Infof("Looking for default routes with IPv%d addresses", uint(family))
|
||||
for _, route := range routes {
|
||||
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
|
||||
|
|
12
vendor/k8s.io/apimachinery/pkg/util/rand/rand.go
generated
vendored
12
vendor/k8s.io/apimachinery/pkg/util/rand/rand.go
generated
vendored
|
@ -72,7 +72,7 @@ func Perm(n int) []int {
|
|||
|
||||
// We omit vowels from the set of available characters to reduce the chances
|
||||
// of "bad words" being formed.
|
||||
var alphanums = []rune("bcdfghjklmnpqrstvwxz0123456789")
|
||||
var alphanums = []rune("bcdfghjklmnpqrstvwxz2456789")
|
||||
|
||||
// String generates a random alphanumeric string, without vowels, which is n
|
||||
// characters long. This will panic if n is less than zero.
|
||||
|
@ -83,3 +83,13 @@ func String(length int) string {
|
|||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and
|
||||
// ensures that strings generated from hash functions appear consistent throughout the API.
|
||||
func SafeEncodeString(s string) string {
|
||||
r := make([]rune, len(s))
|
||||
for i, b := range []rune(s) {
|
||||
r[i] = alphanums[(int(b) % len(alphanums))]
|
||||
}
|
||||
return string(r)
|
||||
}
|
||||
|
|
64
vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
generated
vendored
64
vendor/k8s.io/apimachinery/pkg/util/validation/validation.go
generated
vendored
|
@ -22,6 +22,8 @@ import (
|
|||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
const qnameCharFmt string = "[A-Za-z0-9]"
|
||||
|
@ -67,6 +69,21 @@ func IsQualifiedName(value string) []string {
|
|||
return errs
|
||||
}
|
||||
|
||||
// IsFullyQualifiedName checks if the name is fully qualified.
|
||||
func IsFullyQualifiedName(fldPath *field.Path, name string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
if len(name) == 0 {
|
||||
return append(allErrors, field.Required(fldPath, ""))
|
||||
}
|
||||
if errs := IsDNS1123Subdomain(name); len(errs) > 0 {
|
||||
return append(allErrors, field.Invalid(fldPath, name, strings.Join(errs, ",")))
|
||||
}
|
||||
if len(strings.Split(name, ".")) < 3 {
|
||||
return append(allErrors, field.Invalid(fldPath, name, "should be a domain with at least three segments separated by dots"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
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"
|
||||
const LabelValueMaxLength int = 63
|
||||
|
@ -126,7 +143,7 @@ func IsDNS1123Subdomain(value string) []string {
|
|||
}
|
||||
|
||||
const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
|
||||
const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character"
|
||||
const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character"
|
||||
const DNS1035LabelMaxLength int = 63
|
||||
|
||||
var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$")
|
||||
|
@ -188,6 +205,14 @@ func IsValidPortNum(port int) []string {
|
|||
return []string{InclusiveRangeError(1, 65535)}
|
||||
}
|
||||
|
||||
// IsInRange tests that the argument is in an inclusive range.
|
||||
func IsInRange(value int, min int, max int) []string {
|
||||
if value >= min && value <= max {
|
||||
return nil
|
||||
}
|
||||
return []string{InclusiveRangeError(min, max)}
|
||||
}
|
||||
|
||||
// Now in libcontainer UID/GID limits is 0 ~ 1<<31 - 1
|
||||
// TODO: once we have a type for UID/GID we should make these that type.
|
||||
const (
|
||||
|
@ -277,6 +302,22 @@ func IsHTTPHeaderName(value string) []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
const envVarNameFmt = "[-._a-zA-Z][-._a-zA-Z0-9]*"
|
||||
const envVarNameFmtErrMsg string = "a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit"
|
||||
|
||||
var envVarNameRegexp = regexp.MustCompile("^" + envVarNameFmt + "$")
|
||||
|
||||
// IsEnvVarName tests if a string is a valid environment variable name.
|
||||
func IsEnvVarName(value string) []string {
|
||||
var errs []string
|
||||
if !envVarNameRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(envVarNameFmtErrMsg, envVarNameFmt, "my.env-name", "MY_ENV.NAME", "MyEnvName1"))
|
||||
}
|
||||
|
||||
errs = append(errs, hasChDirPrefix(value)...)
|
||||
return errs
|
||||
}
|
||||
|
||||
const configMapKeyFmt = `[-._a-zA-Z0-9]+`
|
||||
const configMapKeyErrMsg string = "a valid config key must consist of alphanumeric characters, '-', '_' or '.'"
|
||||
|
||||
|
@ -291,13 +332,7 @@ func IsConfigMapKey(value string) []string {
|
|||
if !configMapKeyRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(configMapKeyErrMsg, configMapKeyFmt, "key.name", "KEY_NAME", "key-name"))
|
||||
}
|
||||
if value == "." {
|
||||
errs = append(errs, `must not be '.'`)
|
||||
} else if value == ".." {
|
||||
errs = append(errs, `must not be '..'`)
|
||||
} else if strings.HasPrefix(value, "..") {
|
||||
errs = append(errs, `must not start with '..'`)
|
||||
}
|
||||
errs = append(errs, hasChDirPrefix(value)...)
|
||||
return errs
|
||||
}
|
||||
|
||||
|
@ -341,3 +376,16 @@ func prefixEach(msgs []string, prefix string) []string {
|
|||
func InclusiveRangeError(lo, hi int) string {
|
||||
return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi)
|
||||
}
|
||||
|
||||
func hasChDirPrefix(value string) []string {
|
||||
var errs []string
|
||||
switch {
|
||||
case value == ".":
|
||||
errs = append(errs, `must not be '.'`)
|
||||
case value == "..":
|
||||
errs = append(errs, `must not be '..'`)
|
||||
case strings.HasPrefix(value, ".."):
|
||||
errs = append(errs, `must not start with '..'`)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
|
36
vendor/k8s.io/apimachinery/pkg/util/wait/wait.go
generated
vendored
36
vendor/k8s.io/apimachinery/pkg/util/wait/wait.go
generated
vendored
|
@ -17,8 +17,10 @@ limitations under the License.
|
|||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
@ -36,6 +38,40 @@ var ForeverTestTimeout = time.Second * 30
|
|||
// NeverStop may be passed to Until to make it never stop.
|
||||
var NeverStop <-chan struct{} = make(chan struct{})
|
||||
|
||||
// Group allows to start a group of goroutines and wait for their completion.
|
||||
type Group struct {
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func (g *Group) Wait() {
|
||||
g.wg.Wait()
|
||||
}
|
||||
|
||||
// StartWithChannel starts f in a new goroutine in the group.
|
||||
// stopCh is passed to f as an argument. f should stop when stopCh is available.
|
||||
func (g *Group) StartWithChannel(stopCh <-chan struct{}, f func(stopCh <-chan struct{})) {
|
||||
g.Start(func() {
|
||||
f(stopCh)
|
||||
})
|
||||
}
|
||||
|
||||
// StartWithContext starts f in a new goroutine in the group.
|
||||
// ctx is passed to f as an argument. f should stop when ctx.Done() is available.
|
||||
func (g *Group) StartWithContext(ctx context.Context, f func(context.Context)) {
|
||||
g.Start(func() {
|
||||
f(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
// Start starts f in a new goroutine in the group.
|
||||
func (g *Group) Start(f func()) {
|
||||
g.wg.Add(1)
|
||||
go func() {
|
||||
defer g.wg.Done()
|
||||
f()
|
||||
}()
|
||||
}
|
||||
|
||||
// Forever calls f every period for ever.
|
||||
//
|
||||
// Forever is syntactic sugar on top of Until.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue