Vendor main dependencies.
This commit is contained in:
parent
49a09ab7dd
commit
dd5e3fba01
2738 changed files with 1045689 additions and 0 deletions
190
vendor/k8s.io/client-go/1.5/pkg/util/cert/cert.go
generated
vendored
Normal file
190
vendor/k8s.io/client-go/1.5/pkg/util/cert/cert.go
generated
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
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 cert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
rsaKeySize = 2048
|
||||
duration365d = time.Hour * 24 * 365
|
||||
)
|
||||
|
||||
// Config containes the basic fields required for creating a certificate
|
||||
type Config struct {
|
||||
CommonName string
|
||||
Organization []string
|
||||
AltNames AltNames
|
||||
}
|
||||
|
||||
// AltNames contains the domain names and IP addresses that will be added
|
||||
// to the API Server's x509 certificate SubAltNames field. The values will
|
||||
// be passed directly to the x509.Certificate object.
|
||||
type AltNames struct {
|
||||
DNSNames []string
|
||||
IPs []net.IP
|
||||
}
|
||||
|
||||
// NewPrivateKey creates an RSA private key
|
||||
func NewPrivateKey() (*rsa.PrivateKey, error) {
|
||||
return rsa.GenerateKey(cryptorand.Reader, rsaKeySize)
|
||||
}
|
||||
|
||||
// NewSelfSignedCACert creates a CA certificate
|
||||
func NewSelfSignedCACert(cfg Config, key *rsa.PrivateKey) (*x509.Certificate, error) {
|
||||
now := time.Now()
|
||||
tmpl := x509.Certificate{
|
||||
SerialNumber: new(big.Int).SetInt64(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: cfg.CommonName,
|
||||
Organization: cfg.Organization,
|
||||
},
|
||||
NotBefore: now.UTC(),
|
||||
NotAfter: now.Add(duration365d * 10).UTC(),
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
}
|
||||
|
||||
certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, key.Public(), key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x509.ParseCertificate(certDERBytes)
|
||||
}
|
||||
|
||||
// NewSignedCert creates a signed certificate using the given CA certificate and key
|
||||
func NewSignedCert(cfg Config, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
|
||||
serial, err := cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certTmpl := x509.Certificate{
|
||||
Subject: pkix.Name{
|
||||
CommonName: cfg.CommonName,
|
||||
Organization: caCert.Subject.Organization,
|
||||
},
|
||||
DNSNames: cfg.AltNames.DNSNames,
|
||||
IPAddresses: cfg.AltNames.IPs,
|
||||
SerialNumber: serial,
|
||||
NotBefore: caCert.NotBefore,
|
||||
NotAfter: time.Now().Add(duration365d).UTC(),
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &certTmpl, caCert, key.Public(), caKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x509.ParseCertificate(certDERBytes)
|
||||
}
|
||||
|
||||
// MakeEllipticPrivateKeyPEM creates an ECDSA private key
|
||||
func MakeEllipticPrivateKeyPEM() ([]byte, error) {
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), cryptorand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
derBytes, err := x509.MarshalECPrivateKey(privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
privateKeyPemBlock := &pem.Block{
|
||||
Type: "EC PRIVATE KEY",
|
||||
Bytes: derBytes,
|
||||
}
|
||||
return pem.EncodeToMemory(privateKeyPemBlock), nil
|
||||
}
|
||||
|
||||
// GenerateSelfSignedCert creates a self-signed certificate and key for the given host.
|
||||
// Host may be an IP or a DNS name
|
||||
// You may also specify additional subject alt names (either ip or dns names) for the certificate
|
||||
// The certificate will be created with file mode 0644. The key will be created with file mode 0600.
|
||||
// If the certificate or key files already exist, they will be overwritten.
|
||||
// Any parent directories of the certPath or keyPath will be created as needed with file mode 0755.
|
||||
func GenerateSelfSignedCert(host, certPath, keyPath string, alternateIPs []net.IP, alternateDNS []string) error {
|
||||
priv, err := rsa.GenerateKey(cryptorand.Reader, 2048)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("%s@%d", host, time.Now().Unix()),
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(time.Hour * 24 * 365),
|
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
}
|
||||
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
} else {
|
||||
template.DNSNames = append(template.DNSNames, host)
|
||||
}
|
||||
|
||||
template.IPAddresses = append(template.IPAddresses, alternateIPs...)
|
||||
template.DNSNames = append(template.DNSNames, alternateDNS...)
|
||||
|
||||
derBytes, err := x509.CreateCertificate(cryptorand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate cert
|
||||
certBuffer := bytes.Buffer{}
|
||||
if err := pem.Encode(&certBuffer, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate key
|
||||
keyBuffer := bytes.Buffer{}
|
||||
if err := pem.Encode(&keyBuffer, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := WriteCert(certPath, certBuffer.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := WriteKey(keyPath, keyBuffer.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
81
vendor/k8s.io/client-go/1.5/pkg/util/cert/csr.go
generated
vendored
Normal file
81
vendor/k8s.io/client-go/1.5/pkg/util/cert/csr.go
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
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 cert
|
||||
|
||||
import (
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"net"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/apis/certificates"
|
||||
)
|
||||
|
||||
// ParseCSR extracts the CSR from the API object and decodes it.
|
||||
func ParseCSR(obj *certificates.CertificateSigningRequest) (*x509.CertificateRequest, error) {
|
||||
// extract PEM from request object
|
||||
pemBytes := obj.Spec.Request
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil || block.Type != "CERTIFICATE REQUEST" {
|
||||
return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")
|
||||
}
|
||||
csr, err := x509.ParseCertificateRequest(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return csr, nil
|
||||
}
|
||||
|
||||
// MakeCSR generates a PEM-encoded CSR using the supplied private key, subject, and SANs.
|
||||
// All key types that are implemented via crypto.Signer are supported (This includes *rsa.PrivateKey and *ecdsa.PrivateKey.)
|
||||
func MakeCSR(privateKey interface{}, subject *pkix.Name, dnsSANs []string, ipSANs []net.IP) (csr []byte, err error) {
|
||||
// Customize the signature for RSA keys, depending on the key size
|
||||
var sigType x509.SignatureAlgorithm
|
||||
if privateKey, ok := privateKey.(*rsa.PrivateKey); ok {
|
||||
keySize := privateKey.N.BitLen()
|
||||
switch {
|
||||
case keySize >= 4096:
|
||||
sigType = x509.SHA512WithRSA
|
||||
case keySize >= 3072:
|
||||
sigType = x509.SHA384WithRSA
|
||||
default:
|
||||
sigType = x509.SHA256WithRSA
|
||||
}
|
||||
}
|
||||
|
||||
template := &x509.CertificateRequest{
|
||||
Subject: *subject,
|
||||
SignatureAlgorithm: sigType,
|
||||
DNSNames: dnsSANs,
|
||||
IPAddresses: ipSANs,
|
||||
}
|
||||
|
||||
csr, err = x509.CreateCertificateRequest(cryptorand.Reader, template, privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
csrPemBlock := &pem.Block{
|
||||
Type: "CERTIFICATE REQUEST",
|
||||
Bytes: csr,
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(csrPemBlock), nil
|
||||
}
|
108
vendor/k8s.io/client-go/1.5/pkg/util/cert/io.go
generated
vendored
Normal file
108
vendor/k8s.io/client-go/1.5/pkg/util/cert/io.go
generated
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
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 cert
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// CanReadCertOrKey returns true if the certificate or key files already exists,
|
||||
// otherwise returns false.
|
||||
func CanReadCertOrKey(certPath, keyPath string) bool {
|
||||
if canReadFile(certPath) || canReadFile(keyPath) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// If the file represented by path exists and
|
||||
// readable, returns true otherwise returns false.
|
||||
func canReadFile(path string) bool {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// WriteCert writes the pem-encoded certificate data to certPath.
|
||||
// The certificate file will be created with file mode 0644.
|
||||
// If the certificate file already exists, it will be overwritten.
|
||||
// The parent directory of the certPath will be created as needed with file mode 0755.
|
||||
func WriteCert(certPath string, data []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(certPath, data, os.FileMode(0644)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteKey writes the pem-encoded key data to keyPath.
|
||||
// The key file will be created with file mode 0600.
|
||||
// If the key file already exists, it will be overwritten.
|
||||
// The parent directory of the keyPath will be created as needed with file mode 0755.
|
||||
func WriteKey(keyPath string, data []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(keyPath, data, os.FileMode(0600)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewPool returns an x509.CertPool containing the certificates in the given PEM-encoded file.
|
||||
// Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates
|
||||
func NewPool(filename string) (*x509.CertPool, error) {
|
||||
certs, err := certsFromFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool := x509.NewCertPool()
|
||||
for _, cert := range certs {
|
||||
pool.AddCert(cert)
|
||||
}
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
// certsFromFile returns the x509.Certificates contained in the given PEM-encoded file.
|
||||
// Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates
|
||||
func certsFromFile(file string) ([]*x509.Certificate, error) {
|
||||
if len(file) == 0 {
|
||||
return nil, errors.New("error reading certificates from an empty filename")
|
||||
}
|
||||
pemBlock, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certs, err := ParseCertsPEM(pemBlock)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading %s: %s", file, err)
|
||||
}
|
||||
return certs, nil
|
||||
}
|
107
vendor/k8s.io/client-go/1.5/pkg/util/cert/pem.go
generated
vendored
Normal file
107
vendor/k8s.io/client-go/1.5/pkg/util/cert/pem.go
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
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 cert
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// EncodePublicKeyPEM returns PEM-endcode public data
|
||||
func EncodePublicKeyPEM(key *rsa.PublicKey) ([]byte, error) {
|
||||
der, err := x509.MarshalPKIXPublicKey(key)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
block := pem.Block{
|
||||
Type: "PUBLIC KEY",
|
||||
Bytes: der,
|
||||
}
|
||||
return pem.EncodeToMemory(&block), nil
|
||||
}
|
||||
|
||||
// EncodePrivateKeyPEM returns PEM-encoded private key data
|
||||
func EncodePrivateKeyPEM(key *rsa.PrivateKey) []byte {
|
||||
block := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
return pem.EncodeToMemory(&block)
|
||||
}
|
||||
|
||||
// EncodeCertPEM returns PEM-endcoded certificate data
|
||||
func EncodeCertPEM(cert *x509.Certificate) []byte {
|
||||
block := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: cert.Raw,
|
||||
}
|
||||
return pem.EncodeToMemory(&block)
|
||||
}
|
||||
|
||||
// ParsePrivateKeyPEM returns a private key parsed from a PEM block in the supplied data.
|
||||
// Recognizes PEM blocks for "EC PRIVATE KEY" and "RSA PRIVATE KEY"
|
||||
func ParsePrivateKeyPEM(keyData []byte) (interface{}, error) {
|
||||
for {
|
||||
var privateKeyPemBlock *pem.Block
|
||||
privateKeyPemBlock, keyData = pem.Decode(keyData)
|
||||
if privateKeyPemBlock == nil {
|
||||
// we read all the PEM blocks and didn't recognize one
|
||||
return nil, fmt.Errorf("no private key PEM block found")
|
||||
}
|
||||
|
||||
switch privateKeyPemBlock.Type {
|
||||
case "EC PRIVATE KEY":
|
||||
return x509.ParseECPrivateKey(privateKeyPemBlock.Bytes)
|
||||
case "RSA PRIVATE KEY":
|
||||
return x509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ParseCertsPEM returns the x509.Certificates contained in the given PEM-encoded byte array
|
||||
// Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
|
||||
func ParseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) {
|
||||
ok := false
|
||||
certs := []*x509.Certificate{}
|
||||
for len(pemCerts) > 0 {
|
||||
var block *pem.Block
|
||||
block, pemCerts = pem.Decode(pemCerts)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
// Only use PEM "CERTIFICATE" blocks without extra headers
|
||||
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return certs, err
|
||||
}
|
||||
|
||||
certs = append(certs, cert)
|
||||
ok = true
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return certs, errors.New("could not read any certificates")
|
||||
}
|
||||
return certs, nil
|
||||
}
|
218
vendor/k8s.io/client-go/1.5/pkg/util/clock/clock.go
generated
vendored
Normal file
218
vendor/k8s.io/client-go/1.5/pkg/util/clock/clock.go
generated
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
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
|
||||
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) 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 or Tick
|
||||
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:
|
||||
default:
|
||||
}
|
||||
} else {
|
||||
w.destChan <- t
|
||||
}
|
||||
|
||||
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) 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")
|
||||
}
|
20
vendor/k8s.io/client-go/1.5/pkg/util/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/client-go/1.5/pkg/util/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
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 util implements various utility functions used in both testing and implementation
|
||||
// of Kubernetes. Package util may not depend on any other package in the Kubernetes
|
||||
// package tree.
|
||||
package util
|
18
vendor/k8s.io/client-go/1.5/pkg/util/errors/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/client-go/1.5/pkg/util/errors/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2015 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 errors implements various utility functions and types around errors.
|
||||
package errors
|
182
vendor/k8s.io/client-go/1.5/pkg/util/errors/errors.go
generated
vendored
Normal file
182
vendor/k8s.io/client-go/1.5/pkg/util/errors/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
Copyright 2015 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 errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Aggregate represents an object that contains multiple errors, but does not
|
||||
// necessarily have singular semantic meaning.
|
||||
type Aggregate interface {
|
||||
error
|
||||
Errors() []error
|
||||
}
|
||||
|
||||
// NewAggregate converts a slice of errors into an Aggregate interface, which
|
||||
// is itself an implementation of the error interface. If the slice is empty,
|
||||
// this returns nil.
|
||||
// It will check if any of the element of input error list is nil, to avoid
|
||||
// nil pointer panic when call Error().
|
||||
func NewAggregate(errlist []error) Aggregate {
|
||||
if len(errlist) == 0 {
|
||||
return nil
|
||||
}
|
||||
// In case of input error list contains nil
|
||||
var errs []error
|
||||
for _, e := range errlist {
|
||||
if e != nil {
|
||||
errs = append(errs, e)
|
||||
}
|
||||
}
|
||||
if len(errs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return aggregate(errs)
|
||||
}
|
||||
|
||||
// This helper implements the error and Errors interfaces. Keeping it private
|
||||
// prevents people from making an aggregate of 0 errors, which is not
|
||||
// an error, but does satisfy the error interface.
|
||||
type aggregate []error
|
||||
|
||||
// Error is part of the error interface.
|
||||
func (agg aggregate) Error() string {
|
||||
if len(agg) == 0 {
|
||||
// This should never happen, really.
|
||||
return ""
|
||||
}
|
||||
if len(agg) == 1 {
|
||||
return agg[0].Error()
|
||||
}
|
||||
result := fmt.Sprintf("[%s", agg[0].Error())
|
||||
for i := 1; i < len(agg); i++ {
|
||||
result += fmt.Sprintf(", %s", agg[i].Error())
|
||||
}
|
||||
result += "]"
|
||||
return result
|
||||
}
|
||||
|
||||
// Errors is part of the Aggregate interface.
|
||||
func (agg aggregate) Errors() []error {
|
||||
return []error(agg)
|
||||
}
|
||||
|
||||
// Matcher is used to match errors. Returns true if the error matches.
|
||||
type Matcher func(error) bool
|
||||
|
||||
// FilterOut removes all errors that match any of the matchers from the input
|
||||
// error. If the input is a singular error, only that error is tested. If the
|
||||
// input implements the Aggregate interface, the list of errors will be
|
||||
// processed recursively.
|
||||
//
|
||||
// This can be used, for example, to remove known-OK errors (such as io.EOF or
|
||||
// os.PathNotFound) from a list of errors.
|
||||
func FilterOut(err error, fns ...Matcher) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if agg, ok := err.(Aggregate); ok {
|
||||
return NewAggregate(filterErrors(agg.Errors(), fns...))
|
||||
}
|
||||
if !matchesError(err, fns...) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// matchesError returns true if any Matcher returns true
|
||||
func matchesError(err error, fns ...Matcher) bool {
|
||||
for _, fn := range fns {
|
||||
if fn(err) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// filterErrors returns any errors (or nested errors, if the list contains
|
||||
// nested Errors) for which all fns return false. If no errors
|
||||
// remain a nil list is returned. The resulting silec will have all
|
||||
// nested slices flattened as a side effect.
|
||||
func filterErrors(list []error, fns ...Matcher) []error {
|
||||
result := []error{}
|
||||
for _, err := range list {
|
||||
r := FilterOut(err, fns...)
|
||||
if r != nil {
|
||||
result = append(result, r)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Flatten takes an Aggregate, which may hold other Aggregates in arbitrary
|
||||
// nesting, and flattens them all into a single Aggregate, recursively.
|
||||
func Flatten(agg Aggregate) Aggregate {
|
||||
result := []error{}
|
||||
if agg == nil {
|
||||
return nil
|
||||
}
|
||||
for _, err := range agg.Errors() {
|
||||
if a, ok := err.(Aggregate); ok {
|
||||
r := Flatten(a)
|
||||
if r != nil {
|
||||
result = append(result, r.Errors()...)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
result = append(result, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
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 {
|
||||
if agg, ok := err.(Aggregate); ok && err != nil {
|
||||
switch len(agg.Errors()) {
|
||||
case 1:
|
||||
return agg.Errors()[0]
|
||||
case 0:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// AggregateGoroutines runs the provided functions in parallel, stuffing all
|
||||
// non-nil errors into the returned Aggregate.
|
||||
// Returns nil if all the functions complete successfully.
|
||||
func AggregateGoroutines(funcs ...func() error) Aggregate {
|
||||
errChan := make(chan error, len(funcs))
|
||||
for _, f := range funcs {
|
||||
go func(f func() error) { errChan <- f() }(f)
|
||||
}
|
||||
errs := make([]error, 0)
|
||||
for i := 0; i < cap(errChan); i++ {
|
||||
if err := <-errChan; err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
return NewAggregate(errs)
|
||||
}
|
||||
|
||||
// ErrPreconditionViolated is returned when the precondition is violated
|
||||
var ErrPreconditionViolated = errors.New("precondition is violated")
|
149
vendor/k8s.io/client-go/1.5/pkg/util/flowcontrol/backoff.go
generated
vendored
Normal file
149
vendor/k8s.io/client-go/1.5/pkg/util/flowcontrol/backoff.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2015 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 flowcontrol
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/util/clock"
|
||||
"k8s.io/client-go/1.5/pkg/util/integer"
|
||||
)
|
||||
|
||||
type backoffEntry struct {
|
||||
backoff time.Duration
|
||||
lastUpdate time.Time
|
||||
}
|
||||
|
||||
type Backoff struct {
|
||||
sync.Mutex
|
||||
Clock clock.Clock
|
||||
defaultDuration time.Duration
|
||||
maxDuration time.Duration
|
||||
perItemBackoff map[string]*backoffEntry
|
||||
}
|
||||
|
||||
func NewFakeBackOff(initial, max time.Duration, tc *clock.FakeClock) *Backoff {
|
||||
return &Backoff{
|
||||
perItemBackoff: map[string]*backoffEntry{},
|
||||
Clock: tc,
|
||||
defaultDuration: initial,
|
||||
maxDuration: max,
|
||||
}
|
||||
}
|
||||
|
||||
func NewBackOff(initial, max time.Duration) *Backoff {
|
||||
return &Backoff{
|
||||
perItemBackoff: map[string]*backoffEntry{},
|
||||
Clock: clock.RealClock{},
|
||||
defaultDuration: initial,
|
||||
maxDuration: max,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the current backoff Duration
|
||||
func (p *Backoff) Get(id string) time.Duration {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
var delay time.Duration
|
||||
entry, ok := p.perItemBackoff[id]
|
||||
if ok {
|
||||
delay = entry.backoff
|
||||
}
|
||||
return delay
|
||||
}
|
||||
|
||||
// move backoff to the next mark, capping at maxDuration
|
||||
func (p *Backoff) Next(id string, eventTime time.Time) {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
entry, ok := p.perItemBackoff[id]
|
||||
if !ok || hasExpired(eventTime, entry.lastUpdate, p.maxDuration) {
|
||||
entry = p.initEntryUnsafe(id)
|
||||
} else {
|
||||
delay := entry.backoff * 2 // exponential
|
||||
entry.backoff = time.Duration(integer.Int64Min(int64(delay), int64(p.maxDuration)))
|
||||
}
|
||||
entry.lastUpdate = p.Clock.Now()
|
||||
}
|
||||
|
||||
// Reset forces clearing of all backoff data for a given key.
|
||||
func (p *Backoff) Reset(id string) {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
delete(p.perItemBackoff, id)
|
||||
}
|
||||
|
||||
// Returns True if the elapsed time since eventTime is smaller than the current backoff window
|
||||
func (p *Backoff) IsInBackOffSince(id string, eventTime time.Time) bool {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
entry, ok := p.perItemBackoff[id]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if hasExpired(eventTime, entry.lastUpdate, p.maxDuration) {
|
||||
return false
|
||||
}
|
||||
return p.Clock.Now().Sub(eventTime) < entry.backoff
|
||||
}
|
||||
|
||||
// Returns True if time since lastupdate is less than the current backoff window.
|
||||
func (p *Backoff) IsInBackOffSinceUpdate(id string, eventTime time.Time) bool {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
entry, ok := p.perItemBackoff[id]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if hasExpired(eventTime, entry.lastUpdate, p.maxDuration) {
|
||||
return false
|
||||
}
|
||||
return eventTime.Sub(entry.lastUpdate) < entry.backoff
|
||||
}
|
||||
|
||||
// Garbage collect records that have aged past maxDuration. Backoff users are expected
|
||||
// to invoke this periodically.
|
||||
func (p *Backoff) GC() {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
now := p.Clock.Now()
|
||||
for id, entry := range p.perItemBackoff {
|
||||
if now.Sub(entry.lastUpdate) > p.maxDuration*2 {
|
||||
// GC when entry has not been updated for 2*maxDuration
|
||||
delete(p.perItemBackoff, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Backoff) DeleteEntry(id string) {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
delete(p.perItemBackoff, id)
|
||||
}
|
||||
|
||||
// Take a lock on *Backoff, before calling initEntryUnsafe
|
||||
func (p *Backoff) initEntryUnsafe(id string) *backoffEntry {
|
||||
entry := &backoffEntry{backoff: p.defaultDuration}
|
||||
p.perItemBackoff[id] = entry
|
||||
return entry
|
||||
}
|
||||
|
||||
// After 2*maxDuration we restart the backoff factor to the beginning
|
||||
func hasExpired(eventTime time.Time, lastUpdate time.Time, maxDuration time.Duration) bool {
|
||||
return eventTime.Sub(lastUpdate) > maxDuration*2 // consider stable if it's ok for twice the maxDuration
|
||||
}
|
132
vendor/k8s.io/client-go/1.5/pkg/util/flowcontrol/throttle.go
generated
vendored
Normal file
132
vendor/k8s.io/client-go/1.5/pkg/util/flowcontrol/throttle.go
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
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 flowcontrol
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/juju/ratelimit"
|
||||
)
|
||||
|
||||
type RateLimiter interface {
|
||||
// TryAccept returns true if a token is taken immediately. Otherwise,
|
||||
// it returns false.
|
||||
TryAccept() bool
|
||||
// Accept returns once a token becomes available.
|
||||
Accept()
|
||||
// Stop stops the rate limiter, subsequent calls to CanAccept will return false
|
||||
Stop()
|
||||
// Saturation returns a percentage number which describes how saturated
|
||||
// this rate limiter is.
|
||||
// Usually we use token bucket rate limiter. In that case,
|
||||
// 1.0 means no tokens are available; 0.0 means we have a full bucket of tokens to use.
|
||||
Saturation() float64
|
||||
// QPS returns QPS of this rate limiter
|
||||
QPS() float32
|
||||
}
|
||||
|
||||
type tokenBucketRateLimiter struct {
|
||||
limiter *ratelimit.Bucket
|
||||
qps float32
|
||||
}
|
||||
|
||||
// NewTokenBucketRateLimiter creates a rate limiter which implements a token bucket approach.
|
||||
// The rate limiter allows bursts of up to 'burst' to exceed the QPS, while still maintaining a
|
||||
// smoothed qps rate of 'qps'.
|
||||
// The bucket is initially filled with 'burst' tokens, and refills at a rate of 'qps'.
|
||||
// The maximum number of tokens in the bucket is capped at 'burst'.
|
||||
func NewTokenBucketRateLimiter(qps float32, burst int) RateLimiter {
|
||||
limiter := ratelimit.NewBucketWithRate(float64(qps), int64(burst))
|
||||
return &tokenBucketRateLimiter{
|
||||
limiter: limiter,
|
||||
qps: qps,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tokenBucketRateLimiter) TryAccept() bool {
|
||||
return t.limiter.TakeAvailable(1) == 1
|
||||
}
|
||||
|
||||
func (t *tokenBucketRateLimiter) Saturation() float64 {
|
||||
capacity := t.limiter.Capacity()
|
||||
avail := t.limiter.Available()
|
||||
return float64(capacity-avail) / float64(capacity)
|
||||
}
|
||||
|
||||
// Accept will block until a token becomes available
|
||||
func (t *tokenBucketRateLimiter) Accept() {
|
||||
t.limiter.Wait(1)
|
||||
}
|
||||
|
||||
func (t *tokenBucketRateLimiter) Stop() {
|
||||
}
|
||||
|
||||
func (t *tokenBucketRateLimiter) QPS() float32 {
|
||||
return t.qps
|
||||
}
|
||||
|
||||
type fakeAlwaysRateLimiter struct{}
|
||||
|
||||
func NewFakeAlwaysRateLimiter() RateLimiter {
|
||||
return &fakeAlwaysRateLimiter{}
|
||||
}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) TryAccept() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) Saturation() float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) Stop() {}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) Accept() {}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) QPS() float32 {
|
||||
return 1
|
||||
}
|
||||
|
||||
type fakeNeverRateLimiter struct {
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewFakeNeverRateLimiter() RateLimiter {
|
||||
rl := fakeNeverRateLimiter{}
|
||||
rl.wg.Add(1)
|
||||
return &rl
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) TryAccept() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) Saturation() float64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) Stop() {
|
||||
t.wg.Done()
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) Accept() {
|
||||
t.wg.Wait()
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) QPS() float32 {
|
||||
return 1
|
||||
}
|
167
vendor/k8s.io/client-go/1.5/pkg/util/framer/framer.go
generated
vendored
Normal file
167
vendor/k8s.io/client-go/1.5/pkg/util/framer/framer.go
generated
vendored
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
Copyright 2015 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 framer implements simple frame decoding techniques for an io.ReadCloser
|
||||
package framer
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type lengthDelimitedFrameWriter struct {
|
||||
w io.Writer
|
||||
h [4]byte
|
||||
}
|
||||
|
||||
func NewLengthDelimitedFrameWriter(w io.Writer) io.Writer {
|
||||
return &lengthDelimitedFrameWriter{w: w}
|
||||
}
|
||||
|
||||
// Write writes a single frame to the nested writer, prepending it with the length in
|
||||
// in bytes of data (as a 4 byte, bigendian uint32).
|
||||
func (w *lengthDelimitedFrameWriter) Write(data []byte) (int, error) {
|
||||
binary.BigEndian.PutUint32(w.h[:], uint32(len(data)))
|
||||
n, err := w.w.Write(w.h[:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if n != len(w.h) {
|
||||
return 0, io.ErrShortWrite
|
||||
}
|
||||
return w.w.Write(data)
|
||||
}
|
||||
|
||||
type lengthDelimitedFrameReader struct {
|
||||
r io.ReadCloser
|
||||
remaining int
|
||||
}
|
||||
|
||||
// NewLengthDelimitedFrameReader returns an io.Reader that will decode length-prefixed
|
||||
// frames off of a stream.
|
||||
//
|
||||
// The protocol is:
|
||||
//
|
||||
// stream: message ...
|
||||
// message: prefix body
|
||||
// prefix: 4 byte uint32 in BigEndian order, denotes length of body
|
||||
// body: bytes (0..prefix)
|
||||
//
|
||||
// If the buffer passed to Read is not long enough to contain an entire frame, io.ErrShortRead
|
||||
// will be returned along with the number of bytes read.
|
||||
func NewLengthDelimitedFrameReader(r io.ReadCloser) io.ReadCloser {
|
||||
return &lengthDelimitedFrameReader{r: r}
|
||||
}
|
||||
|
||||
// Read attempts to read an entire frame into data. If that is not possible, io.ErrShortBuffer
|
||||
// is returned and subsequent calls will attempt to read the last frame. A frame is complete when
|
||||
// err is nil.
|
||||
func (r *lengthDelimitedFrameReader) Read(data []byte) (int, error) {
|
||||
if r.remaining <= 0 {
|
||||
header := [4]byte{}
|
||||
n, err := io.ReadAtLeast(r.r, header[:4], 4)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if n != 4 {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
frameLength := int(binary.BigEndian.Uint32(header[:]))
|
||||
r.remaining = frameLength
|
||||
}
|
||||
|
||||
expect := r.remaining
|
||||
max := expect
|
||||
if max > len(data) {
|
||||
max = len(data)
|
||||
}
|
||||
n, err := io.ReadAtLeast(r.r, data[:max], int(max))
|
||||
r.remaining -= n
|
||||
if err == io.ErrShortBuffer || r.remaining > 0 {
|
||||
return n, io.ErrShortBuffer
|
||||
}
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if n != expect {
|
||||
return n, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (r *lengthDelimitedFrameReader) Close() error {
|
||||
return r.r.Close()
|
||||
}
|
||||
|
||||
type jsonFrameReader struct {
|
||||
r io.ReadCloser
|
||||
decoder *json.Decoder
|
||||
remaining []byte
|
||||
}
|
||||
|
||||
// NewJSONFramedReader returns an io.Reader that will decode individual JSON objects off
|
||||
// of a wire.
|
||||
//
|
||||
// The boundaries between each frame are valid JSON objects. A JSON parsing error will terminate
|
||||
// the read.
|
||||
func NewJSONFramedReader(r io.ReadCloser) io.ReadCloser {
|
||||
return &jsonFrameReader{
|
||||
r: r,
|
||||
decoder: json.NewDecoder(r),
|
||||
}
|
||||
}
|
||||
|
||||
// ReadFrame decodes the next JSON object in the stream, or returns an error. The returned
|
||||
// byte slice will be modified the next time ReadFrame is invoked and should not be altered.
|
||||
func (r *jsonFrameReader) Read(data []byte) (int, error) {
|
||||
// Return whatever remaining data exists from an in progress frame
|
||||
if n := len(r.remaining); n > 0 {
|
||||
if n <= len(data) {
|
||||
data = append(data[0:0], r.remaining...)
|
||||
r.remaining = nil
|
||||
return n, nil
|
||||
}
|
||||
|
||||
n = len(data)
|
||||
data = append(data[0:0], r.remaining[:n]...)
|
||||
r.remaining = r.remaining[n:]
|
||||
return n, io.ErrShortBuffer
|
||||
}
|
||||
|
||||
// RawMessage#Unmarshal appends to data - we reset the slice down to 0 and will either see
|
||||
// data written to data, or be larger than data and a different array.
|
||||
n := len(data)
|
||||
m := json.RawMessage(data[:0])
|
||||
if err := r.decoder.Decode(&m); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// If capacity of data is less than length of the message, decoder will allocate a new slice
|
||||
// and set m to it, which means we need to copy the partial result back into data and preserve
|
||||
// the remaining result for subsequent reads.
|
||||
if len(m) > n {
|
||||
data = append(data[0:0], m[:n]...)
|
||||
r.remaining = m[n:]
|
||||
return n, io.ErrShortBuffer
|
||||
}
|
||||
return len(m), nil
|
||||
}
|
||||
|
||||
func (r *jsonFrameReader) Close() error {
|
||||
return r.r.Close()
|
||||
}
|
67
vendor/k8s.io/client-go/1.5/pkg/util/integer/integer.go
generated
vendored
Normal file
67
vendor/k8s.io/client-go/1.5/pkg/util/integer/integer.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
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 integer
|
||||
|
||||
func IntMax(a, b int) int {
|
||||
if b > a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func IntMin(a, b int) int {
|
||||
if b < a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func Int32Max(a, b int32) int32 {
|
||||
if b > a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func Int32Min(a, b int32) int32 {
|
||||
if b < a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func Int64Max(a, b int64) int64 {
|
||||
if b > a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func Int64Min(a, b int64) int64 {
|
||||
if b < a {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// RoundToInt32 rounds floats into integer numbers.
|
||||
func RoundToInt32(a float64) int32 {
|
||||
if a < 0 {
|
||||
return int32(a - 0.5)
|
||||
}
|
||||
return int32(a + 0.5)
|
||||
}
|
372
vendor/k8s.io/client-go/1.5/pkg/util/intstr/generated.pb.go
generated
vendored
Normal file
372
vendor/k8s.io/client-go/1.5/pkg/util/intstr/generated.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,372 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo.
|
||||
// source: k8s.io/kubernetes/pkg/util/intstr/generated.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package intstr is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
k8s.io/kubernetes/pkg/util/intstr/generated.proto
|
||||
|
||||
It has these top-level messages:
|
||||
IntOrString
|
||||
*/
|
||||
package intstr
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import io "io"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
const _ = proto.GoGoProtoPackageIsVersion1
|
||||
|
||||
func (m *IntOrString) Reset() { *m = IntOrString{} }
|
||||
func (*IntOrString) ProtoMessage() {}
|
||||
func (*IntOrString) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*IntOrString)(nil), "k8s.io.client-go.1.5.pkg.util.intstr.IntOrString")
|
||||
}
|
||||
func (m *IntOrString) Marshal() (data []byte, err error) {
|
||||
size := m.Size()
|
||||
data = make([]byte, size)
|
||||
n, err := m.MarshalTo(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data[:n], nil
|
||||
}
|
||||
|
||||
func (m *IntOrString) MarshalTo(data []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
data[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintGenerated(data, i, uint64(m.Type))
|
||||
data[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintGenerated(data, i, uint64(m.IntVal))
|
||||
data[i] = 0x1a
|
||||
i++
|
||||
i = encodeVarintGenerated(data, i, uint64(len(m.StrVal)))
|
||||
i += copy(data[i:], m.StrVal)
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeFixed64Generated(data []byte, offset int, v uint64) int {
|
||||
data[offset] = uint8(v)
|
||||
data[offset+1] = uint8(v >> 8)
|
||||
data[offset+2] = uint8(v >> 16)
|
||||
data[offset+3] = uint8(v >> 24)
|
||||
data[offset+4] = uint8(v >> 32)
|
||||
data[offset+5] = uint8(v >> 40)
|
||||
data[offset+6] = uint8(v >> 48)
|
||||
data[offset+7] = uint8(v >> 56)
|
||||
return offset + 8
|
||||
}
|
||||
func encodeFixed32Generated(data []byte, offset int, v uint32) int {
|
||||
data[offset] = uint8(v)
|
||||
data[offset+1] = uint8(v >> 8)
|
||||
data[offset+2] = uint8(v >> 16)
|
||||
data[offset+3] = uint8(v >> 24)
|
||||
return offset + 4
|
||||
}
|
||||
func encodeVarintGenerated(data []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
data[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
data[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *IntOrString) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
n += 1 + sovGenerated(uint64(m.Type))
|
||||
n += 1 + sovGenerated(uint64(m.IntVal))
|
||||
l = len(m.StrVal)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenerated(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func sozGenerated(x uint64) (n int) {
|
||||
return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *IntOrString) Unmarshal(data []byte) error {
|
||||
l := len(data)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: IntOrString: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: IntOrString: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
|
||||
}
|
||||
m.Type = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
m.Type |= (Type(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field IntVal", wireType)
|
||||
}
|
||||
m.IntVal = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
m.IntVal |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field StrVal", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.StrVal = string(data[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(data[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenerated(data []byte) (n int, err error) {
|
||||
l := len(data)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if data[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
iNdEx += length
|
||||
if length < 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
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 256 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x32, 0xcc, 0xb6, 0x28, 0xd6,
|
||||
0xcb, 0xcc, 0xd7, 0xcf, 0x2e, 0x4d, 0x4a, 0x2d, 0xca, 0x4b, 0x2d, 0x49, 0x2d, 0xd6, 0x2f, 0xc8,
|
||||
0x4e, 0xd7, 0x2f, 0x2d, 0xc9, 0xcc, 0xd1, 0xcf, 0xcc, 0x2b, 0x29, 0x2e, 0x29, 0xd2, 0x4f, 0x4f,
|
||||
0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x84,
|
||||
0x68, 0xd1, 0x43, 0x68, 0xd1, 0x03, 0x6a, 0xd1, 0x03, 0x69, 0xd1, 0x83, 0x68, 0x91, 0xd2, 0x4d,
|
||||
0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, 0xcf, 0xd7, 0x07,
|
||||
0xeb, 0x4c, 0x2a, 0x4d, 0x03, 0xf3, 0xc0, 0x1c, 0x30, 0x0b, 0x62, 0xa2, 0xd2, 0x44, 0x46, 0x2e,
|
||||
0x6e, 0xcf, 0xbc, 0x12, 0xff, 0xa2, 0xe0, 0x92, 0xa2, 0xcc, 0xbc, 0x74, 0x21, 0x0d, 0x2e, 0x96,
|
||||
0x92, 0xca, 0x82, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x66, 0x27, 0x91, 0x13, 0xf7, 0xe4, 0x19,
|
||||
0x1e, 0xdd, 0x93, 0x67, 0x09, 0x01, 0x8a, 0xfd, 0x82, 0xd2, 0x41, 0x60, 0x15, 0x42, 0x6a, 0x5c,
|
||||
0x6c, 0x40, 0x2b, 0xc3, 0x12, 0x73, 0x24, 0x98, 0x80, 0x6a, 0x59, 0x9d, 0xf8, 0xa0, 0x6a, 0xd9,
|
||||
0x3c, 0xc1, 0xa2, 0x41, 0x50, 0x59, 0x90, 0x3a, 0xa0, 0xbb, 0x40, 0xea, 0x98, 0x81, 0xea, 0x38,
|
||||
0x11, 0xea, 0x82, 0xc1, 0xa2, 0x41, 0x50, 0x59, 0x2b, 0x8e, 0x19, 0x0b, 0xe4, 0x19, 0x1a, 0xee,
|
||||
0x28, 0x30, 0x38, 0x69, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0x01, 0x88, 0x6f, 0x00, 0x71, 0xc3, 0x23,
|
||||
0x39, 0xc6, 0x13, 0x40, 0x7c, 0x01, 0x88, 0x1f, 0x00, 0xf1, 0x84, 0xc7, 0x72, 0x0c, 0x51, 0x6c,
|
||||
0x10, 0xcf, 0x02, 0x02, 0x00, 0x00, 0xff, 0xff, 0x68, 0x57, 0xfb, 0xfa, 0x43, 0x01, 0x00, 0x00,
|
||||
}
|
162
vendor/k8s.io/client-go/1.5/pkg/util/intstr/intstr.go
generated
vendored
Normal file
162
vendor/k8s.io/client-go/1.5/pkg/util/intstr/intstr.go
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
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 intstr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/genericapiserver/openapi/common"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
// IntOrString is a type that can hold an int32 or a string. When used in
|
||||
// JSON or YAML marshalling and unmarshalling, it produces or consumes the
|
||||
// inner type. This allows you to have, for example, a JSON field that can
|
||||
// accept a name or number.
|
||||
// TODO: Rename to Int32OrString
|
||||
//
|
||||
// +protobuf=true
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
// +k8s:openapi-gen=true
|
||||
type IntOrString struct {
|
||||
Type Type `protobuf:"varint,1,opt,name=type,casttype=Type"`
|
||||
IntVal int32 `protobuf:"varint,2,opt,name=intVal"`
|
||||
StrVal string `protobuf:"bytes,3,opt,name=strVal"`
|
||||
}
|
||||
|
||||
// Type represents the stored type of IntOrString.
|
||||
type Type int
|
||||
|
||||
const (
|
||||
Int Type = iota // The IntOrString holds an int.
|
||||
String // The IntOrString holds a string.
|
||||
)
|
||||
|
||||
// FromInt creates an IntOrString object with an int32 value. It is
|
||||
// your responsibility not to call this method with a value greater
|
||||
// than int32.
|
||||
// TODO: convert to (val int32)
|
||||
func FromInt(val int) IntOrString {
|
||||
return IntOrString{Type: Int, IntVal: int32(val)}
|
||||
}
|
||||
|
||||
// FromString creates an IntOrString object with a string value.
|
||||
func FromString(val string) IntOrString {
|
||||
return IntOrString{Type: String, StrVal: val}
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (intstr *IntOrString) UnmarshalJSON(value []byte) error {
|
||||
if value[0] == '"' {
|
||||
intstr.Type = String
|
||||
return json.Unmarshal(value, &intstr.StrVal)
|
||||
}
|
||||
intstr.Type = Int
|
||||
return json.Unmarshal(value, &intstr.IntVal)
|
||||
}
|
||||
|
||||
// String returns the string value, or the Itoa of the int value.
|
||||
func (intstr *IntOrString) String() string {
|
||||
if intstr.Type == String {
|
||||
return intstr.StrVal
|
||||
}
|
||||
return strconv.Itoa(intstr.IntValue())
|
||||
}
|
||||
|
||||
// IntValue returns the IntVal if type Int, or if
|
||||
// it is a String, will attempt a conversion to int.
|
||||
func (intstr *IntOrString) IntValue() int {
|
||||
if intstr.Type == String {
|
||||
i, _ := strconv.Atoi(intstr.StrVal)
|
||||
return i
|
||||
}
|
||||
return int(intstr.IntVal)
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface.
|
||||
func (intstr IntOrString) MarshalJSON() ([]byte, error) {
|
||||
switch intstr.Type {
|
||||
case Int:
|
||||
return json.Marshal(intstr.IntVal)
|
||||
case String:
|
||||
return json.Marshal(intstr.StrVal)
|
||||
default:
|
||||
return []byte{}, fmt.Errorf("impossible IntOrString.Type")
|
||||
}
|
||||
}
|
||||
|
||||
func (_ IntOrString) OpenAPIDefinition() common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "int-or-string",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (intstr *IntOrString) Fuzz(c fuzz.Continue) {
|
||||
if intstr == nil {
|
||||
return
|
||||
}
|
||||
if c.RandBool() {
|
||||
intstr.Type = Int
|
||||
c.Fuzz(&intstr.IntVal)
|
||||
intstr.StrVal = ""
|
||||
} else {
|
||||
intstr.Type = String
|
||||
intstr.IntVal = 0
|
||||
c.Fuzz(&intstr.StrVal)
|
||||
}
|
||||
}
|
||||
|
||||
func GetValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool) (int, error) {
|
||||
value, isPercent, err := getIntOrPercentValue(intOrPercent)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid value for IntOrString: %v", err)
|
||||
}
|
||||
if isPercent {
|
||||
if roundUp {
|
||||
value = int(math.Ceil(float64(value) * (float64(total)) / 100))
|
||||
} else {
|
||||
value = int(math.Floor(float64(value) * (float64(total)) / 100))
|
||||
}
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func getIntOrPercentValue(intOrStr *IntOrString) (int, bool, error) {
|
||||
switch intOrStr.Type {
|
||||
case Int:
|
||||
return intOrStr.IntValue(), false, nil
|
||||
case String:
|
||||
s := strings.Replace(intOrStr.StrVal, "%", "", -1)
|
||||
v, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return 0, false, fmt.Errorf("invalid value %q: %v", intOrStr.StrVal, err)
|
||||
}
|
||||
return int(v), true, nil
|
||||
}
|
||||
return 0, false, fmt.Errorf("invalid type: neither int nor percentage")
|
||||
}
|
107
vendor/k8s.io/client-go/1.5/pkg/util/json/json.go
generated
vendored
Normal file
107
vendor/k8s.io/client-go/1.5/pkg/util/json/json.go
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright 2015 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 json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// NewEncoder delegates to json.NewEncoder
|
||||
// It is only here so this package can be a drop-in for common encoding/json uses
|
||||
func NewEncoder(w io.Writer) *json.Encoder {
|
||||
return json.NewEncoder(w)
|
||||
}
|
||||
|
||||
// Marshal delegates to json.Marshal
|
||||
// It is only here so this package can be a drop-in for common encoding/json uses
|
||||
func Marshal(v interface{}) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals the given data
|
||||
// If v is a *map[string]interface{}, numbers are converted to int64 or float64
|
||||
func Unmarshal(data []byte, v interface{}) error {
|
||||
switch v := v.(type) {
|
||||
case *map[string]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 convertMapNumbers(*v)
|
||||
|
||||
default:
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
}
|
||||
|
||||
// convertMapNumbers traverses the map, converting any json.Number values to int64 or float64.
|
||||
// values which are map[string]interface{} or []interface{} are recursively visited
|
||||
func convertMapNumbers(m map[string]interface{}) error {
|
||||
var err error
|
||||
for k, v := range m {
|
||||
switch v := v.(type) {
|
||||
case json.Number:
|
||||
m[k], err = convertNumber(v)
|
||||
case map[string]interface{}:
|
||||
err = convertMapNumbers(v)
|
||||
case []interface{}:
|
||||
err = convertSliceNumbers(v)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// convertSliceNumbers traverses the slice, converting any json.Number values to int64 or float64.
|
||||
// values which are map[string]interface{} or []interface{} are recursively visited
|
||||
func convertSliceNumbers(s []interface{}) error {
|
||||
var err error
|
||||
for i, v := range s {
|
||||
switch v := v.(type) {
|
||||
case json.Number:
|
||||
s[i], err = convertNumber(v)
|
||||
case map[string]interface{}:
|
||||
err = convertMapNumbers(v)
|
||||
case []interface{}:
|
||||
err = convertSliceNumbers(v)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// convertNumber converts a json.Number to an int64 or float64, or returns an error
|
||||
func convertNumber(n json.Number) (interface{}, error) {
|
||||
// Attempt to convert to an int64 first
|
||||
if i, err := n.Int64(); err == nil {
|
||||
return i, nil
|
||||
}
|
||||
// Return a float64 (default json.Decode() behavior)
|
||||
// An overflow will return an error
|
||||
return n.Float64()
|
||||
}
|
18
vendor/k8s.io/client-go/1.5/pkg/util/labels/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/client-go/1.5/pkg/util/labels/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
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 labels provides utilities to work with Kubernetes labels.
|
||||
package labels
|
126
vendor/k8s.io/client-go/1.5/pkg/util/labels/labels.go
generated
vendored
Normal file
126
vendor/k8s.io/client-go/1.5/pkg/util/labels/labels.go
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
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 labels
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// Clones the given map and returns a new map with the given key and value added.
|
||||
// Returns the given map, if labelKey is empty.
|
||||
func CloneAndAddLabel(labels map[string]string, labelKey string, labelValue uint32) map[string]string {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return labels
|
||||
}
|
||||
// Clone.
|
||||
newLabels := map[string]string{}
|
||||
for key, value := range labels {
|
||||
newLabels[key] = value
|
||||
}
|
||||
newLabels[labelKey] = fmt.Sprintf("%d", labelValue)
|
||||
return newLabels
|
||||
}
|
||||
|
||||
// CloneAndRemoveLabel clones the given map and returns a new map with the given key removed.
|
||||
// Returns the given map, if labelKey is empty.
|
||||
func CloneAndRemoveLabel(labels map[string]string, labelKey string) map[string]string {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return labels
|
||||
}
|
||||
// Clone.
|
||||
newLabels := map[string]string{}
|
||||
for key, value := range labels {
|
||||
newLabels[key] = value
|
||||
}
|
||||
delete(newLabels, labelKey)
|
||||
return newLabels
|
||||
}
|
||||
|
||||
// AddLabel returns a map with the given key and value added to the given map.
|
||||
func AddLabel(labels map[string]string, labelKey string, labelValue string) map[string]string {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return labels
|
||||
}
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
labels[labelKey] = labelValue
|
||||
return labels
|
||||
}
|
||||
|
||||
// Clones the given selector and returns a new selector with the given key and value added.
|
||||
// Returns the given selector, if labelKey is empty.
|
||||
func CloneSelectorAndAddLabel(selector *unversioned.LabelSelector, labelKey string, labelValue uint32) *unversioned.LabelSelector {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return selector
|
||||
}
|
||||
|
||||
// Clone.
|
||||
newSelector := new(unversioned.LabelSelector)
|
||||
|
||||
// TODO(madhusudancs): Check if you can use deepCopy_extensions_LabelSelector here.
|
||||
newSelector.MatchLabels = make(map[string]string)
|
||||
if selector.MatchLabels != nil {
|
||||
for key, val := range selector.MatchLabels {
|
||||
newSelector.MatchLabels[key] = val
|
||||
}
|
||||
}
|
||||
newSelector.MatchLabels[labelKey] = fmt.Sprintf("%d", labelValue)
|
||||
|
||||
if selector.MatchExpressions != nil {
|
||||
newMExps := make([]unversioned.LabelSelectorRequirement, len(selector.MatchExpressions))
|
||||
for i, me := range selector.MatchExpressions {
|
||||
newMExps[i].Key = me.Key
|
||||
newMExps[i].Operator = me.Operator
|
||||
if me.Values != nil {
|
||||
newMExps[i].Values = make([]string, len(me.Values))
|
||||
copy(newMExps[i].Values, me.Values)
|
||||
} else {
|
||||
newMExps[i].Values = nil
|
||||
}
|
||||
}
|
||||
newSelector.MatchExpressions = newMExps
|
||||
} else {
|
||||
newSelector.MatchExpressions = nil
|
||||
}
|
||||
|
||||
return newSelector
|
||||
}
|
||||
|
||||
// AddLabelToSelector returns a selector with the given key and value added to the given selector's MatchLabels.
|
||||
func AddLabelToSelector(selector *unversioned.LabelSelector, labelKey string, labelValue string) *unversioned.LabelSelector {
|
||||
if labelKey == "" {
|
||||
// Don't need to add a label.
|
||||
return selector
|
||||
}
|
||||
if selector.MatchLabels == nil {
|
||||
selector.MatchLabels = make(map[string]string)
|
||||
}
|
||||
selector.MatchLabels[labelKey] = labelValue
|
||||
return selector
|
||||
}
|
||||
|
||||
// SelectorHasLabel checks if the given selector contains the given label key in its MatchLabels
|
||||
func SelectorHasLabel(selector *unversioned.LabelSelector, labelKey string) bool {
|
||||
return len(selector.MatchLabels[labelKey]) > 0
|
||||
}
|
263
vendor/k8s.io/client-go/1.5/pkg/util/net/http.go
generated
vendored
Normal file
263
vendor/k8s.io/client-go/1.5/pkg/util/net/http.go
generated
vendored
Normal file
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
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 (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
// 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
|
||||
// connection closure errors (strongly correlated) and callers that need to
|
||||
// differentiate probable errors in connection behavior between normal "this is
|
||||
// disconnected" should use the method.
|
||||
func IsProbableEOF(err error) bool {
|
||||
if uerr, ok := err.(*url.Error); ok {
|
||||
err = uerr.Err
|
||||
}
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
return true
|
||||
case err.Error() == "http: can't write HTTP request on broken connection":
|
||||
return true
|
||||
case strings.Contains(err.Error(), "connection reset by peer"):
|
||||
return true
|
||||
case strings.Contains(strings.ToLower(err.Error()), "use of closed network connection"):
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var defaultTransport = http.DefaultTransport.(*http.Transport)
|
||||
|
||||
// SetOldTransportDefaults applies the defaults from http.DefaultTransport
|
||||
// for the Proxy, Dial, and TLSHandshakeTimeout fields if unset
|
||||
func SetOldTransportDefaults(t *http.Transport) *http.Transport {
|
||||
if t.Proxy == nil || isDefault(t.Proxy) {
|
||||
// http.ProxyFromEnvironment doesn't respect CIDRs and that makes it impossible to exclude things like pod and service IPs from proxy settings
|
||||
// ProxierWithNoProxyCIDR allows CIDR rules in NO_PROXY
|
||||
t.Proxy = NewProxierWithNoProxyCIDR(http.ProxyFromEnvironment)
|
||||
}
|
||||
if t.Dial == nil {
|
||||
t.Dial = defaultTransport.Dial
|
||||
}
|
||||
if t.TLSHandshakeTimeout == 0 {
|
||||
t.TLSHandshakeTimeout = defaultTransport.TLSHandshakeTimeout
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// SetTransportDefaults applies the defaults from http.DefaultTransport
|
||||
// for the Proxy, Dial, and TLSHandshakeTimeout fields if unset
|
||||
func SetTransportDefaults(t *http.Transport) *http.Transport {
|
||||
t = SetOldTransportDefaults(t)
|
||||
// Allow clients to disable http2 if needed.
|
||||
if s := os.Getenv("DISABLE_HTTP2"); len(s) > 0 {
|
||||
glog.Infof("HTTP2 has been explicitly disabled")
|
||||
} else {
|
||||
if err := http2.ConfigureTransport(t); err != nil {
|
||||
glog.Warningf("Transport failed http2 configuration: %v", err)
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
type RoundTripperWrapper interface {
|
||||
http.RoundTripper
|
||||
WrappedRoundTripper() http.RoundTripper
|
||||
}
|
||||
|
||||
type DialFunc func(net, addr string) (net.Conn, error)
|
||||
|
||||
func Dialer(transport http.RoundTripper) (DialFunc, error) {
|
||||
if transport == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch transport := transport.(type) {
|
||||
case *http.Transport:
|
||||
return transport.Dial, nil
|
||||
case RoundTripperWrapper:
|
||||
return Dialer(transport.WrappedRoundTripper())
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown transport type: %v", transport)
|
||||
}
|
||||
}
|
||||
|
||||
// CloneTLSConfig returns a tls.Config with all exported fields except SessionTicketsDisabled and SessionTicketKey copied.
|
||||
// This makes it safe to call CloneTLSConfig on a config in active use by a server.
|
||||
// TODO: replace with tls.Config#Clone when we move to go1.8
|
||||
func CloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{}
|
||||
}
|
||||
return &tls.Config{
|
||||
Rand: cfg.Rand,
|
||||
Time: cfg.Time,
|
||||
Certificates: cfg.Certificates,
|
||||
NameToCertificate: cfg.NameToCertificate,
|
||||
GetCertificate: cfg.GetCertificate,
|
||||
RootCAs: cfg.RootCAs,
|
||||
NextProtos: cfg.NextProtos,
|
||||
ServerName: cfg.ServerName,
|
||||
ClientAuth: cfg.ClientAuth,
|
||||
ClientCAs: cfg.ClientCAs,
|
||||
InsecureSkipVerify: cfg.InsecureSkipVerify,
|
||||
CipherSuites: cfg.CipherSuites,
|
||||
PreferServerCipherSuites: cfg.PreferServerCipherSuites,
|
||||
ClientSessionCache: cfg.ClientSessionCache,
|
||||
MinVersion: cfg.MinVersion,
|
||||
MaxVersion: cfg.MaxVersion,
|
||||
CurvePreferences: cfg.CurvePreferences,
|
||||
}
|
||||
}
|
||||
|
||||
func TLSClientConfig(transport http.RoundTripper) (*tls.Config, error) {
|
||||
if transport == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch transport := transport.(type) {
|
||||
case *http.Transport:
|
||||
return transport.TLSClientConfig, nil
|
||||
case RoundTripperWrapper:
|
||||
return TLSClientConfig(transport.WrappedRoundTripper())
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown transport type: %v", transport)
|
||||
}
|
||||
}
|
||||
|
||||
func FormatURL(scheme string, host string, port int, path string) *url.URL {
|
||||
return &url.URL{
|
||||
Scheme: scheme,
|
||||
Host: net.JoinHostPort(host, strconv.Itoa(port)),
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
||||
func GetHTTPClient(req *http.Request) string {
|
||||
if userAgent, ok := req.Header["User-Agent"]; ok {
|
||||
if len(userAgent) > 0 {
|
||||
return userAgent[0]
|
||||
}
|
||||
}
|
||||
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 {
|
||||
hdr := req.Header
|
||||
// First check the X-Forwarded-For header for requests via proxy.
|
||||
hdrForwardedFor := hdr.Get("X-Forwarded-For")
|
||||
if hdrForwardedFor != "" {
|
||||
// X-Forwarded-For can be a csv of IPs in case of multiple proxies.
|
||||
// Use the first valid one.
|
||||
parts := strings.Split(hdrForwardedFor, ",")
|
||||
for _, part := range parts {
|
||||
ip := net.ParseIP(strings.TrimSpace(part))
|
||||
if ip != nil {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try the X-Real-Ip header.
|
||||
hdrRealIp := hdr.Get("X-Real-Ip")
|
||||
if hdrRealIp != "" {
|
||||
ip := net.ParseIP(hdrRealIp)
|
||||
if ip != nil {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to Remote Address in request, which will give the correct client IP when there is no proxy.
|
||||
// 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)
|
||||
}
|
||||
|
||||
// Fallback if Remote Address was just IP.
|
||||
return net.ParseIP(req.RemoteAddr)
|
||||
}
|
||||
|
||||
var defaultProxyFuncPointer = fmt.Sprintf("%p", http.ProxyFromEnvironment)
|
||||
|
||||
// isDefault checks to see if the transportProxierFunc is pointing to the default one
|
||||
func isDefault(transportProxier func(*http.Request) (*url.URL, error)) bool {
|
||||
transportProxierPointer := fmt.Sprintf("%p", transportProxier)
|
||||
return transportProxierPointer == defaultProxyFuncPointer
|
||||
}
|
||||
|
||||
// NewProxierWithNoProxyCIDR constructs a Proxier function that respects CIDRs in NO_PROXY and delegates if
|
||||
// no matching CIDRs are found
|
||||
func NewProxierWithNoProxyCIDR(delegate func(req *http.Request) (*url.URL, error)) func(req *http.Request) (*url.URL, error) {
|
||||
// we wrap the default method, so we only need to perform our check if the NO_PROXY envvar has a CIDR in it
|
||||
noProxyEnv := os.Getenv("NO_PROXY")
|
||||
noProxyRules := strings.Split(noProxyEnv, ",")
|
||||
|
||||
cidrs := []*net.IPNet{}
|
||||
for _, noProxyRule := range noProxyRules {
|
||||
_, cidr, _ := net.ParseCIDR(noProxyRule)
|
||||
if cidr != nil {
|
||||
cidrs = append(cidrs, cidr)
|
||||
}
|
||||
}
|
||||
|
||||
if len(cidrs) == 0 {
|
||||
return delegate
|
||||
}
|
||||
|
||||
return func(req *http.Request) (*url.URL, error) {
|
||||
host := req.URL.Host
|
||||
// for some urls, the Host is already the host, not the host:port
|
||||
if net.ParseIP(host) == nil {
|
||||
var err error
|
||||
host, _, err = net.SplitHostPort(req.URL.Host)
|
||||
if err != nil {
|
||||
return delegate(req)
|
||||
}
|
||||
}
|
||||
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
return delegate(req)
|
||||
}
|
||||
|
||||
for _, cidr := range cidrs {
|
||||
if cidr.Contains(ip) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
return delegate(req)
|
||||
}
|
||||
}
|
278
vendor/k8s.io/client-go/1.5/pkg/util/net/interface.go
generated
vendored
Normal file
278
vendor/k8s.io/client-go/1.5/pkg/util/net/interface.go
generated
vendored
Normal file
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
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 (
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type Route struct {
|
||||
Interface string
|
||||
Destination net.IP
|
||||
Gateway net.IP
|
||||
// TODO: add more fields here if needed
|
||||
}
|
||||
|
||||
func getRoutes(input io.Reader) ([]Route, error) {
|
||||
routes := []Route{}
|
||||
if input == nil {
|
||||
return nil, fmt.Errorf("input is nil")
|
||||
}
|
||||
scanner := bufio.NewReader(input)
|
||||
for {
|
||||
line, err := scanner.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
//ignore the headers in the route info
|
||||
if strings.HasPrefix(line, "Iface") {
|
||||
continue
|
||||
}
|
||||
fields := strings.Fields(line)
|
||||
routes = append(routes, Route{})
|
||||
route := &routes[len(routes)-1]
|
||||
route.Interface = fields[0]
|
||||
ip, err := parseIP(fields[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
route.Destination = ip
|
||||
ip, err = parseIP(fields[2])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
route.Gateway = ip
|
||||
}
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
func parseIP(str string) (net.IP, error) {
|
||||
if str == "" {
|
||||
return nil, fmt.Errorf("input is nil")
|
||||
}
|
||||
bytes, err := hex.DecodeString(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//TODO add ipv6 support
|
||||
if len(bytes) != net.IPv4len {
|
||||
return nil, fmt.Errorf("only IPv4 is supported")
|
||||
}
|
||||
bytes[0], bytes[1], bytes[2], bytes[3] = bytes[3], bytes[2], bytes[1], bytes[0]
|
||||
return net.IP(bytes), nil
|
||||
}
|
||||
|
||||
func isInterfaceUp(intf *net.Interface) bool {
|
||||
if intf == nil {
|
||||
return false
|
||||
}
|
||||
if intf.Flags&net.FlagUp != 0 {
|
||||
glog.V(4).Infof("Interface %v is up", intf.Name)
|
||||
return true
|
||||
}
|
||||
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) {
|
||||
if len(addrs) > 0 {
|
||||
for i := range addrs {
|
||||
glog.V(4).Infof("Checking addr %s.", addrs[i].String())
|
||||
ip, _, err := net.ParseCIDR(addrs[i].String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//Only IPv4
|
||||
//TODO : add IPv6 support
|
||||
if ip.To4() != nil {
|
||||
if !ip.IsLoopback() && !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
|
||||
glog.V(4).Infof("IP found %v", ip)
|
||||
return ip, nil
|
||||
} else {
|
||||
glog.V(4).Infof("Loopback/link-local found %v", ip)
|
||||
}
|
||||
} else {
|
||||
glog.V(4).Infof("%v is not a valid IPv4 address", ip)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
|
||||
intf, err := nw.InterfaceByName(intfName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isInterfaceUp(intf) {
|
||||
addrs, err := nw.Addrs(intf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
glog.V(4).Infof("Interface %q has %d addresses :%v.", intfName, len(addrs), addrs)
|
||||
finalIP, err := getFinalIP(addrs)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func flagsSet(flags net.Flags, test net.Flags) bool {
|
||||
return flags&test != 0
|
||||
}
|
||||
|
||||
func flagsClear(flags net.Flags, test net.Flags) bool {
|
||||
return flags&test == 0
|
||||
}
|
||||
|
||||
func chooseHostInterfaceNativeGo() (net.IP, error) {
|
||||
intfs, err := net.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 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 ip != nil {
|
||||
// This interface should suffice.
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
//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.
|
||||
func ChooseHostInterface() (net.IP, error) {
|
||||
inFile, err := os.Open("/proc/net/route")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return chooseHostInterfaceNativeGo()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer inFile.Close()
|
||||
var nw networkInterfacer = networkInterface{}
|
||||
return chooseHostInterfaceFromRoute(inFile, nw)
|
||||
}
|
||||
|
||||
type networkInterfacer interface {
|
||||
InterfaceByName(intfName string) (*net.Interface, error)
|
||||
Addrs(intf *net.Interface) ([]net.Addr, error)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (_ networkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
|
||||
addrs, err := intf.Addrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
func chooseHostInterfaceFromRoute(inFile io.Reader, nw networkInterfacer) (net.IP, error) {
|
||||
routes, err := getRoutes(inFile)
|
||||
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 err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if finalIP != nil {
|
||||
glog.V(4).Infof("Choosing 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
|
||||
}
|
||||
|
||||
// If bind-address is usable, return it directly
|
||||
// If bind-address is not usable (unset, 0.0.0.0, or loopback), we will use the host's default
|
||||
// interface.
|
||||
func ChooseBindAddress(bindAddress net.IP) (net.IP, error) {
|
||||
if bindAddress == nil || bindAddress.IsUnspecified() || bindAddress.IsLoopback() {
|
||||
hostIP, err := ChooseHostInterface()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bindAddress = hostIP
|
||||
}
|
||||
return bindAddress, nil
|
||||
}
|
113
vendor/k8s.io/client-go/1.5/pkg/util/net/port_range.go
generated
vendored
Normal file
113
vendor/k8s.io/client-go/1.5/pkg/util/net/port_range.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2015 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"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PortRange represents a range of TCP/UDP ports. To represent a single port,
|
||||
// set Size to 1.
|
||||
type PortRange struct {
|
||||
Base int
|
||||
Size int
|
||||
}
|
||||
|
||||
// Contains tests whether a given port falls within the PortRange.
|
||||
func (pr *PortRange) Contains(p int) bool {
|
||||
return (p >= pr.Base) && ((p - pr.Base) < pr.Size)
|
||||
}
|
||||
|
||||
// String converts the PortRange to a string representation, which can be
|
||||
// parsed by PortRange.Set or ParsePortRange.
|
||||
func (pr PortRange) String() string {
|
||||
if pr.Size == 0 {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%d-%d", pr.Base, pr.Base+pr.Size-1)
|
||||
}
|
||||
|
||||
// Set parses a string of the form "min-max", inclusive at both ends, and
|
||||
// sets the PortRange from it. This is part of the flag.Value and pflag.Value
|
||||
// interfaces.
|
||||
func (pr *PortRange) Set(value string) error {
|
||||
value = strings.TrimSpace(value)
|
||||
|
||||
// TODO: Accept "80" syntax
|
||||
// TODO: Accept "80+8" syntax
|
||||
|
||||
if value == "" {
|
||||
pr.Base = 0
|
||||
pr.Size = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
hyphenIndex := strings.Index(value, "-")
|
||||
if hyphenIndex == -1 {
|
||||
return fmt.Errorf("expected hyphen in port range")
|
||||
}
|
||||
|
||||
var err error
|
||||
var low int
|
||||
var high int
|
||||
low, err = strconv.Atoi(value[:hyphenIndex])
|
||||
if err == nil {
|
||||
high, err = strconv.Atoi(value[hyphenIndex+1:])
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse port range: %s: %v", value, err)
|
||||
}
|
||||
|
||||
if low > 65535 || high > 65535 {
|
||||
return fmt.Errorf("the port range cannot be greater than 65535: %s", value)
|
||||
}
|
||||
|
||||
if high < low {
|
||||
return fmt.Errorf("end port cannot be less than start port: %s", value)
|
||||
}
|
||||
|
||||
pr.Base = low
|
||||
pr.Size = 1 + high - low
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns a descriptive string about this type. This is part of the
|
||||
// pflag.Value interface.
|
||||
func (*PortRange) Type() string {
|
||||
return "portRange"
|
||||
}
|
||||
|
||||
// ParsePortRange parses a string of the form "min-max", inclusive at both
|
||||
// ends, and initializs a new PortRange from it.
|
||||
func ParsePortRange(value string) (*PortRange, error) {
|
||||
pr := &PortRange{}
|
||||
err := pr.Set(value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
func ParsePortRangeOrDie(value string) *PortRange {
|
||||
pr, err := ParsePortRange(value)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("couldn't parse port range %q: %v", value, err))
|
||||
}
|
||||
return pr
|
||||
}
|
77
vendor/k8s.io/client-go/1.5/pkg/util/net/port_split.go
generated
vendored
Normal file
77
vendor/k8s.io/client-go/1.5/pkg/util/net/port_split.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright 2015 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 (
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
||||
)
|
||||
|
||||
var validSchemes = sets.NewString("http", "https", "")
|
||||
|
||||
// SplitSchemeNamePort takes a string of the following forms:
|
||||
// * "<name>", returns "", "<name>","", true
|
||||
// * "<name>:<port>", returns "", "<name>","<port>",true
|
||||
// * "<scheme>:<name>:<port>", returns "<scheme>","<name>","<port>",true
|
||||
//
|
||||
// Name must be non-empty or valid will be returned false.
|
||||
// Scheme must be "http" or "https" if specified
|
||||
// Port is returned as a string, and it is not required to be numeric (could be
|
||||
// used for a named port, for example).
|
||||
func SplitSchemeNamePort(id string) (scheme, name, port string, valid bool) {
|
||||
parts := strings.Split(id, ":")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
name = parts[0]
|
||||
case 2:
|
||||
name = parts[0]
|
||||
port = parts[1]
|
||||
case 3:
|
||||
scheme = parts[0]
|
||||
name = parts[1]
|
||||
port = parts[2]
|
||||
default:
|
||||
return "", "", "", false
|
||||
}
|
||||
|
||||
if len(name) > 0 && validSchemes.Has(scheme) {
|
||||
return scheme, name, port, true
|
||||
} else {
|
||||
return "", "", "", false
|
||||
}
|
||||
}
|
||||
|
||||
// JoinSchemeNamePort returns a string that specifies the scheme, name, and port:
|
||||
// * "<name>"
|
||||
// * "<name>:<port>"
|
||||
// * "<scheme>:<name>:<port>"
|
||||
// None of the parameters may contain a ':' character
|
||||
// Name is required
|
||||
// Scheme must be "", "http", or "https"
|
||||
func JoinSchemeNamePort(scheme, name, port string) string {
|
||||
if len(scheme) > 0 {
|
||||
// Must include three segments to specify scheme
|
||||
return scheme + ":" + name + ":" + port
|
||||
}
|
||||
if len(port) > 0 {
|
||||
// Must include two segments to specify port
|
||||
return name + ":" + port
|
||||
}
|
||||
// Return name alone
|
||||
return name
|
||||
}
|
36
vendor/k8s.io/client-go/1.5/pkg/util/net/util.go
generated
vendored
Normal file
36
vendor/k8s.io/client-go/1.5/pkg/util/net/util.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
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 (
|
||||
"net"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// IPNetEqual checks if the two input IPNets are representing the same subnet.
|
||||
// For example,
|
||||
// 10.0.0.1/24 and 10.0.0.0/24 are the same subnet.
|
||||
// 10.0.0.1/24 and 10.0.0.0/25 are not the same subnet.
|
||||
func IPNetEqual(ipnet1, ipnet2 *net.IPNet) bool {
|
||||
if ipnet1 == nil || ipnet2 == nil {
|
||||
return false
|
||||
}
|
||||
if reflect.DeepEqual(ipnet1.Mask, ipnet2.Mask) && ipnet1.Contains(ipnet2.IP) && ipnet2.Contains(ipnet1.IP) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
54
vendor/k8s.io/client-go/1.5/pkg/util/parsers/parsers.go
generated
vendored
Normal file
54
vendor/k8s.io/client-go/1.5/pkg/util/parsers/parsers.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright 2015 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 parsers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
dockerref "github.com/docker/distribution/reference"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultImageTag = "latest"
|
||||
)
|
||||
|
||||
// ParseImageName parses a docker image string into three parts: repo, tag and digest.
|
||||
// If both tag and digest are empty, a default image tag will be returned.
|
||||
func ParseImageName(image string) (string, string, string, error) {
|
||||
named, err := dockerref.ParseNamed(image)
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("couldn't parse image name: %v", err)
|
||||
}
|
||||
|
||||
repoToPull := named.Name()
|
||||
var tag, digest string
|
||||
|
||||
tagged, ok := named.(dockerref.Tagged)
|
||||
if ok {
|
||||
tag = tagged.Tag()
|
||||
}
|
||||
|
||||
digested, ok := named.(dockerref.Digested)
|
||||
if ok {
|
||||
digest = digested.Digest().String()
|
||||
}
|
||||
// If no tag was specified, use the default "latest".
|
||||
if len(tag) == 0 && len(digest) == 0 {
|
||||
tag = DefaultImageTag
|
||||
}
|
||||
return repoToPull, tag, digest, nil
|
||||
}
|
83
vendor/k8s.io/client-go/1.5/pkg/util/rand/rand.go
generated
vendored
Normal file
83
vendor/k8s.io/client-go/1.5/pkg/util/rand/rand.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2015 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 rand provides utilities related to randomization.
|
||||
package rand
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyz0123456789")
|
||||
var numLetters = len(letters)
|
||||
var rng = struct {
|
||||
sync.Mutex
|
||||
rand *rand.Rand
|
||||
}{
|
||||
rand: rand.New(rand.NewSource(time.Now().UTC().UnixNano())),
|
||||
}
|
||||
|
||||
// Intn generates an integer in range [0,max).
|
||||
// By design this should panic if input is invalid, <= 0.
|
||||
func Intn(max int) int {
|
||||
rng.Lock()
|
||||
defer rng.Unlock()
|
||||
return rng.rand.Intn(max)
|
||||
}
|
||||
|
||||
// IntnRange generates an integer in range [min,max).
|
||||
// By design this should panic if input is invalid, <= 0.
|
||||
func IntnRange(min, max int) int {
|
||||
rng.Lock()
|
||||
defer rng.Unlock()
|
||||
return rng.rand.Intn(max-min) + min
|
||||
}
|
||||
|
||||
// IntnRange generates an int64 integer in range [min,max).
|
||||
// By design this should panic if input is invalid, <= 0.
|
||||
func Int63nRange(min, max int64) int64 {
|
||||
rng.Lock()
|
||||
defer rng.Unlock()
|
||||
return rng.rand.Int63n(max-min) + min
|
||||
}
|
||||
|
||||
// Seed seeds the rng with the provided seed.
|
||||
func Seed(seed int64) {
|
||||
rng.Lock()
|
||||
defer rng.Unlock()
|
||||
|
||||
rng.rand = rand.New(rand.NewSource(seed))
|
||||
}
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n)
|
||||
// from the default Source.
|
||||
func Perm(n int) []int {
|
||||
rng.Lock()
|
||||
defer rng.Unlock()
|
||||
return rng.rand.Perm(n)
|
||||
}
|
||||
|
||||
// String generates a random alphanumeric string n characters long. This will
|
||||
// panic if n is less than zero.
|
||||
func String(length int) string {
|
||||
b := make([]rune, length)
|
||||
for i := range b {
|
||||
b[i] = letters[Intn(numLetters)]
|
||||
}
|
||||
return string(b)
|
||||
}
|
128
vendor/k8s.io/client-go/1.5/pkg/util/runtime/runtime.go
generated
vendored
Normal file
128
vendor/k8s.io/client-go/1.5/pkg/util/runtime/runtime.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
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 runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
var (
|
||||
// ReallyCrash controls the behavior of HandleCrash and now defaults
|
||||
// true. It's still exposed so components can optionally set to false
|
||||
// to restore prior behavior.
|
||||
ReallyCrash = true
|
||||
)
|
||||
|
||||
// PanicHandlers is a list of functions which will be invoked when a panic happens.
|
||||
var PanicHandlers = []func(interface{}){logPanic}
|
||||
|
||||
// HandleCrash simply catches a crash and logs an error. Meant to be called via
|
||||
// defer. Additional context-specific handlers can be provided, and will be
|
||||
// called in case of panic. HandleCrash actually crashes, after calling the
|
||||
// handlers and logging the panic message.
|
||||
//
|
||||
// TODO: remove this function. We are switching to a world where it's safe for
|
||||
// apiserver to panic, since it will be restarted by kubelet. At the beginning
|
||||
// of the Kubernetes project, nothing was going to restart apiserver and so
|
||||
// catching panics was important. But it's actually much simpler for montoring
|
||||
// software if we just exit when an unexpected panic happens.
|
||||
func HandleCrash(additionalHandlers ...func(interface{})) {
|
||||
if r := recover(); r != nil {
|
||||
for _, fn := range PanicHandlers {
|
||||
fn(r)
|
||||
}
|
||||
for _, fn := range additionalHandlers {
|
||||
fn(r)
|
||||
}
|
||||
if ReallyCrash {
|
||||
// Actually proceed to panic.
|
||||
panic(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// logPanic logs the caller tree when a panic occurs.
|
||||
func logPanic(r interface{}) {
|
||||
callers := getCallers(r)
|
||||
glog.Errorf("Observed a panic: %#v (%v)\n%v", r, r, callers)
|
||||
}
|
||||
|
||||
func getCallers(r interface{}) string {
|
||||
callers := ""
|
||||
for i := 0; true; i++ {
|
||||
_, file, line, ok := runtime.Caller(i)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
callers = callers + fmt.Sprintf("%v:%v\n", file, line)
|
||||
}
|
||||
|
||||
return callers
|
||||
}
|
||||
|
||||
// ErrorHandlers is a list of functions which will be invoked when an unreturnable
|
||||
// error occurs.
|
||||
var ErrorHandlers = []func(error){logError}
|
||||
|
||||
// HandlerError is a method to invoke when a non-user facing piece of code cannot
|
||||
// return an error and needs to indicate it has been ignored. Invoking this method
|
||||
// is preferable to logging the error - the default behavior is to log but the
|
||||
// errors may be sent to a remote server for analysis.
|
||||
func HandleError(err error) {
|
||||
// this is sometimes called with a nil error. We probably shouldn't fail and should do nothing instead
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, fn := range ErrorHandlers {
|
||||
fn(err)
|
||||
}
|
||||
}
|
||||
|
||||
// logError prints an error with the call stack of the location it was reported
|
||||
func logError(err error) {
|
||||
glog.ErrorDepth(2, err)
|
||||
}
|
||||
|
||||
// GetCaller returns the caller of the function that calls it.
|
||||
func GetCaller() string {
|
||||
var pc [1]uintptr
|
||||
runtime.Callers(3, pc[:])
|
||||
f := runtime.FuncForPC(pc[0])
|
||||
if f == nil {
|
||||
return fmt.Sprintf("Unable to find caller")
|
||||
}
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
// RecoverFromPanic replaces the specified error with an error containing the
|
||||
// original error, and the call tree when a panic occurs. This enables error
|
||||
// handlers to handle errors and panics the same way.
|
||||
func RecoverFromPanic(err *error) {
|
||||
if r := recover(); r != nil {
|
||||
callers := getCallers(r)
|
||||
|
||||
*err = fmt.Errorf(
|
||||
"recovered from panic %q. (err=%v) Call stack:\n%v",
|
||||
r,
|
||||
*err,
|
||||
callers)
|
||||
}
|
||||
}
|
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/byte.go
generated
vendored
Normal file
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/byte.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by set-gen. Do not edit it manually!
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption.
|
||||
type Byte map[byte]Empty
|
||||
|
||||
// New creates a Byte from a list of values.
|
||||
func NewByte(items ...byte) Byte {
|
||||
ss := Byte{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func ByteKeySet(theMap interface{}) Byte {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := Byte{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(byte))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Byte) Insert(items ...byte) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Byte) Delete(items ...byte) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Byte) Has(item byte) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Byte) HasAll(items ...byte) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Byte) HasAny(items ...byte) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 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 Byte) Difference(s2 Byte) Byte {
|
||||
result := NewByte()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Byte) Union(s2 Byte) Byte {
|
||||
result := NewByte()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Byte) Intersection(s2 Byte) Byte {
|
||||
var walk, other Byte
|
||||
result := NewByte()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Byte) IsSuperset(s2 Byte) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
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 (s1 Byte) Equal(s2 Byte) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfByte []byte
|
||||
|
||||
func (s sortableSliceOfByte) Len() int { return len(s) }
|
||||
func (s sortableSliceOfByte) Less(i, j int) bool { return lessByte(s[i], s[j]) }
|
||||
func (s sortableSliceOfByte) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted byte slice.
|
||||
func (s Byte) List() []byte {
|
||||
res := make(sortableSliceOfByte, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []byte(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Byte) UnsortedList() []byte {
|
||||
res := make([]byte, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Byte) PopAny() (byte, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue byte
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Byte) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessByte(lhs, rhs byte) bool {
|
||||
return lhs < rhs
|
||||
}
|
20
vendor/k8s.io/client-go/1.5/pkg/util/sets/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/client-go/1.5/pkg/util/sets/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by set-gen. Do not edit it manually!
|
||||
|
||||
// Package sets has auto-generated set types.
|
||||
package sets
|
23
vendor/k8s.io/client-go/1.5/pkg/util/sets/empty.go
generated
vendored
Normal file
23
vendor/k8s.io/client-go/1.5/pkg/util/sets/empty.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by set-gen. Do not edit it manually!
|
||||
|
||||
package sets
|
||||
|
||||
// Empty is public since it is used by some internal API objects for conversions between external
|
||||
// string arrays and internal sets, and conversion logic requires public types today.
|
||||
type Empty struct{}
|
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/int.go
generated
vendored
Normal file
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/int.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by set-gen. Do not edit it manually!
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption.
|
||||
type Int map[int]Empty
|
||||
|
||||
// New creates a Int from a list of values.
|
||||
func NewInt(items ...int) Int {
|
||||
ss := Int{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// IntKeySet creates a Int from a keys of a map[int](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func IntKeySet(theMap interface{}) Int {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := Int{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(int))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Int) Insert(items ...int) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Int) Delete(items ...int) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Int) Has(item int) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Int) HasAll(items ...int) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Int) HasAny(items ...int) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 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 Int) Difference(s2 Int) Int {
|
||||
result := NewInt()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Int) Union(s2 Int) Int {
|
||||
result := NewInt()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Int) Intersection(s2 Int) Int {
|
||||
var walk, other Int
|
||||
result := NewInt()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Int) IsSuperset(s2 Int) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
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 (s1 Int) Equal(s2 Int) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfInt []int
|
||||
|
||||
func (s sortableSliceOfInt) Len() int { return len(s) }
|
||||
func (s sortableSliceOfInt) Less(i, j int) bool { return lessInt(s[i], s[j]) }
|
||||
func (s sortableSliceOfInt) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted int slice.
|
||||
func (s Int) List() []int {
|
||||
res := make(sortableSliceOfInt, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []int(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int) UnsortedList() []int {
|
||||
res := make([]int, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Int) PopAny() (int, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue int
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Int) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessInt(lhs, rhs int) bool {
|
||||
return lhs < rhs
|
||||
}
|
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/int64.go
generated
vendored
Normal file
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/int64.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by set-gen. Do not edit it manually!
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption.
|
||||
type Int64 map[int64]Empty
|
||||
|
||||
// New creates a Int64 from a list of values.
|
||||
func NewInt64(items ...int64) Int64 {
|
||||
ss := Int64{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func Int64KeySet(theMap interface{}) Int64 {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := Int64{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(int64))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Int64) Insert(items ...int64) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Int64) Delete(items ...int64) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Int64) Has(item int64) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Int64) HasAll(items ...int64) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Int64) HasAny(items ...int64) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 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 Int64) Difference(s2 Int64) Int64 {
|
||||
result := NewInt64()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Int64) Union(s2 Int64) Int64 {
|
||||
result := NewInt64()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Int64) Intersection(s2 Int64) Int64 {
|
||||
var walk, other Int64
|
||||
result := NewInt64()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Int64) IsSuperset(s2 Int64) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
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 (s1 Int64) Equal(s2 Int64) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfInt64 []int64
|
||||
|
||||
func (s sortableSliceOfInt64) Len() int { return len(s) }
|
||||
func (s sortableSliceOfInt64) Less(i, j int) bool { return lessInt64(s[i], s[j]) }
|
||||
func (s sortableSliceOfInt64) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted int64 slice.
|
||||
func (s Int64) List() []int64 {
|
||||
res := make(sortableSliceOfInt64, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []int64(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int64) UnsortedList() []int64 {
|
||||
res := make([]int64, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Int64) PopAny() (int64, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue int64
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Int64) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessInt64(lhs, rhs int64) bool {
|
||||
return lhs < rhs
|
||||
}
|
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/string.go
generated
vendored
Normal file
203
vendor/k8s.io/client-go/1.5/pkg/util/sets/string.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by set-gen. Do not edit it manually!
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption.
|
||||
type String map[string]Empty
|
||||
|
||||
// New creates a String from a list of values.
|
||||
func NewString(items ...string) String {
|
||||
ss := String{}
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// StringKeySet creates a String from a keys of a map[string](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func StringKeySet(theMap interface{}) String {
|
||||
v := reflect.ValueOf(theMap)
|
||||
ret := String{}
|
||||
|
||||
for _, keyValue := range v.MapKeys() {
|
||||
ret.Insert(keyValue.Interface().(string))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s String) Insert(items ...string) {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s String) Delete(items ...string) {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s String) Has(item string) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s String) HasAll(items ...string) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s String) HasAny(items ...string) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 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 String) Difference(s2 String) String {
|
||||
result := NewString()
|
||||
for key := range s {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 String) Union(s2 String) String {
|
||||
result := NewString()
|
||||
for key := range s1 {
|
||||
result.Insert(key)
|
||||
}
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 String) Intersection(s2 String) String {
|
||||
var walk, other String
|
||||
result := NewString()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 String) IsSuperset(s2 String) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
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 (s1 String) Equal(s2 String) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfString []string
|
||||
|
||||
func (s sortableSliceOfString) Len() int { return len(s) }
|
||||
func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) }
|
||||
func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// List returns the contents as a sorted string slice.
|
||||
func (s String) List() []string {
|
||||
res := make(sortableSliceOfString, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return []string(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s String) UnsortedList() []string {
|
||||
res := make([]string, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s String) PopAny() (string, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue string
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s String) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func lessString(lhs, rhs string) bool {
|
||||
return lhs < rhs
|
||||
}
|
56
vendor/k8s.io/client-go/1.5/pkg/util/string_flag.go
generated
vendored
Normal file
56
vendor/k8s.io/client-go/1.5/pkg/util/string_flag.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
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 util
|
||||
|
||||
// StringFlag is a string flag compatible with flags and pflags that keeps track of whether it had a value supplied or not.
|
||||
type StringFlag struct {
|
||||
// If Set has been invoked this value is true
|
||||
provided bool
|
||||
// The exact value provided on the flag
|
||||
value string
|
||||
}
|
||||
|
||||
func NewStringFlag(defaultVal string) StringFlag {
|
||||
return StringFlag{value: defaultVal}
|
||||
}
|
||||
|
||||
func (f *StringFlag) Default(value string) {
|
||||
f.value = value
|
||||
}
|
||||
|
||||
func (f StringFlag) String() string {
|
||||
return f.value
|
||||
}
|
||||
|
||||
func (f StringFlag) Value() string {
|
||||
return f.value
|
||||
}
|
||||
|
||||
func (f *StringFlag) Set(value string) error {
|
||||
f.value = value
|
||||
f.provided = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f StringFlag) Provided() bool {
|
||||
return f.provided
|
||||
}
|
||||
|
||||
func (f *StringFlag) Type() string {
|
||||
return "string"
|
||||
}
|
48
vendor/k8s.io/client-go/1.5/pkg/util/template.go
generated
vendored
Normal file
48
vendor/k8s.io/client-go/1.5/pkg/util/template.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright 2015 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 util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/doc"
|
||||
"io"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func wrap(indent string, s string) string {
|
||||
var buf bytes.Buffer
|
||||
doc.ToText(&buf, s, indent, indent+" ", 80-len(indent))
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// ExecuteTemplate executes templateText with data and output written to w.
|
||||
func ExecuteTemplate(w io.Writer, templateText string, data interface{}) error {
|
||||
t := template.New("top")
|
||||
t.Funcs(template.FuncMap{
|
||||
"trim": strings.TrimSpace,
|
||||
"wrap": wrap,
|
||||
})
|
||||
template.Must(t.Parse(templateText))
|
||||
return t.Execute(w, data)
|
||||
}
|
||||
|
||||
func ExecuteTemplateToString(templateText string, data interface{}) (string, error) {
|
||||
b := bytes.Buffer{}
|
||||
err := ExecuteTemplate(&b, templateText, data)
|
||||
return b.String(), err
|
||||
}
|
72
vendor/k8s.io/client-go/1.5/pkg/util/trace.go
generated
vendored
Normal file
72
vendor/k8s.io/client-go/1.5/pkg/util/trace.go
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright 2015 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 util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type traceStep struct {
|
||||
stepTime time.Time
|
||||
msg string
|
||||
}
|
||||
|
||||
type Trace struct {
|
||||
name string
|
||||
startTime time.Time
|
||||
steps []traceStep
|
||||
}
|
||||
|
||||
func NewTrace(name string) *Trace {
|
||||
return &Trace{name, time.Now(), nil}
|
||||
}
|
||||
|
||||
func (t *Trace) Step(msg string) {
|
||||
if t.steps == nil {
|
||||
// traces almost always have less than 6 steps, do this to avoid more than a single allocation
|
||||
t.steps = make([]traceStep, 0, 6)
|
||||
}
|
||||
t.steps = append(t.steps, traceStep{time.Now(), msg})
|
||||
}
|
||||
|
||||
func (t *Trace) Log() {
|
||||
endTime := time.Now()
|
||||
var buffer bytes.Buffer
|
||||
|
||||
buffer.WriteString(fmt.Sprintf("Trace %q (started %v):\n", t.name, t.startTime))
|
||||
lastStepTime := t.startTime
|
||||
for _, step := range t.steps {
|
||||
buffer.WriteString(fmt.Sprintf("[%v] [%v] %v\n", step.stepTime.Sub(t.startTime), step.stepTime.Sub(lastStepTime), step.msg))
|
||||
lastStepTime = step.stepTime
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("[%v] [%v] END\n", endTime.Sub(t.startTime), endTime.Sub(lastStepTime)))
|
||||
glog.Info(buffer.String())
|
||||
}
|
||||
|
||||
func (t *Trace) LogIfLong(threshold time.Duration) {
|
||||
if time.Since(t.startTime) >= threshold {
|
||||
t.Log()
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Trace) TotalTime() time.Duration {
|
||||
return time.Since(t.startTime)
|
||||
}
|
27
vendor/k8s.io/client-go/1.5/pkg/util/umask.go
generated
vendored
Normal file
27
vendor/k8s.io/client-go/1.5/pkg/util/umask.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
// +build !windows
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func Umask(mask int) (old int, err error) {
|
||||
return syscall.Umask(mask), nil
|
||||
}
|
27
vendor/k8s.io/client-go/1.5/pkg/util/umask_windows.go
generated
vendored
Normal file
27
vendor/k8s.io/client-go/1.5/pkg/util/umask_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
// +build windows
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
func Umask(mask int) (old int, err error) {
|
||||
return 0, errors.New("platform and architecture is not supported")
|
||||
}
|
147
vendor/k8s.io/client-go/1.5/pkg/util/util.go
generated
vendored
Normal file
147
vendor/k8s.io/client-go/1.5/pkg/util/util.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Takes a list of strings and compiles them into a list of regular expressions
|
||||
func CompileRegexps(regexpStrings []string) ([]*regexp.Regexp, error) {
|
||||
regexps := []*regexp.Regexp{}
|
||||
for _, regexpStr := range regexpStrings {
|
||||
r, err := regexp.Compile(regexpStr)
|
||||
if err != nil {
|
||||
return []*regexp.Regexp{}, err
|
||||
}
|
||||
regexps = append(regexps, r)
|
||||
}
|
||||
return regexps, nil
|
||||
}
|
||||
|
||||
// Detects if using systemd as the init system
|
||||
// Please note that simply reading /proc/1/cmdline can be misleading because
|
||||
// some installation of various init programs can automatically make /sbin/init
|
||||
// a symlink or even a renamed version of their main program.
|
||||
// TODO(dchen1107): realiably detects the init system using on the system:
|
||||
// systemd, upstart, initd, etc.
|
||||
func UsingSystemdInitSystem() bool {
|
||||
if _, err := os.Stat("/run/systemd/system"); err == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Tests whether all pointer fields in a struct are nil. This is useful when,
|
||||
// for example, an API struct is handled by plugins which need to distinguish
|
||||
// "no plugin accepted this spec" from "this spec is empty".
|
||||
//
|
||||
// This function is only valid for structs and pointers to structs. Any other
|
||||
// type will cause a panic. Passing a typed nil pointer will return true.
|
||||
func AllPtrFieldsNil(obj interface{}) bool {
|
||||
v := reflect.ValueOf(obj)
|
||||
if !v.IsValid() {
|
||||
panic(fmt.Sprintf("reflect.ValueOf() produced a non-valid Value for %#v", obj))
|
||||
}
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return true
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if v.Field(i).Kind() == reflect.Ptr && !v.Field(i).IsNil() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FileExists(filename string) (bool, error) {
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
return false, nil
|
||||
} else if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// borrowed from ioutil.ReadDir
|
||||
// ReadDir reads the directory named by dirname and returns
|
||||
// a list of directory entries, minus those with lstat errors
|
||||
func ReadDirNoExit(dirname string) ([]os.FileInfo, []error, error) {
|
||||
if dirname == "" {
|
||||
dirname = "."
|
||||
}
|
||||
|
||||
f, err := os.Open(dirname)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
names, err := f.Readdirnames(-1)
|
||||
list := make([]os.FileInfo, 0, len(names))
|
||||
errs := make([]error, 0, len(names))
|
||||
for _, filename := range names {
|
||||
fip, lerr := os.Lstat(dirname + "/" + filename)
|
||||
if os.IsNotExist(lerr) {
|
||||
// File disappeared between readdir + stat.
|
||||
// Just treat it as if it didn't exist.
|
||||
continue
|
||||
}
|
||||
|
||||
list = append(list, fip)
|
||||
errs = append(errs, lerr)
|
||||
}
|
||||
|
||||
return list, errs, nil
|
||||
}
|
||||
|
||||
// IntPtr returns a pointer to an int
|
||||
func IntPtr(i int) *int {
|
||||
o := i
|
||||
return &o
|
||||
}
|
||||
|
||||
// Int32Ptr returns a pointer to an int32
|
||||
func Int32Ptr(i int32) *int32 {
|
||||
o := i
|
||||
return &o
|
||||
}
|
||||
|
||||
// IntPtrDerefOr dereference the int ptr and returns it i not nil,
|
||||
// else returns def.
|
||||
func IntPtrDerefOr(ptr *int, def int) int {
|
||||
if ptr != nil {
|
||||
return *ptr
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
// Int32PtrDerefOr dereference the int32 ptr and returns it i not nil,
|
||||
// else returns def.
|
||||
func Int32PtrDerefOr(ptr *int32, def int32) int32 {
|
||||
if ptr != nil {
|
||||
return *ptr
|
||||
}
|
||||
return def
|
||||
}
|
42
vendor/k8s.io/client-go/1.5/pkg/util/uuid/uuid.go
generated
vendored
Normal file
42
vendor/k8s.io/client-go/1.5/pkg/util/uuid/uuid.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
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 uuid
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/pborman/uuid"
|
||||
"k8s.io/client-go/1.5/pkg/types"
|
||||
)
|
||||
|
||||
var uuidLock sync.Mutex
|
||||
var lastUUID uuid.UUID
|
||||
|
||||
func NewUUID() types.UID {
|
||||
uuidLock.Lock()
|
||||
defer uuidLock.Unlock()
|
||||
result := uuid.NewUUID()
|
||||
// The UUID package is naive and can generate identical UUIDs if the
|
||||
// time interval is quick enough.
|
||||
// The UUID uses 100 ns increments so it's short enough to actively
|
||||
// wait for a new value.
|
||||
for uuid.Equal(lastUUID, result) == true {
|
||||
result = uuid.NewUUID()
|
||||
}
|
||||
lastUUID = result
|
||||
return types.UID(result.String())
|
||||
}
|
228
vendor/k8s.io/client-go/1.5/pkg/util/validation/field/errors.go
generated
vendored
Normal file
228
vendor/k8s.io/client-go/1.5/pkg/util/validation/field/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
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 field
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
utilerrors "k8s.io/client-go/1.5/pkg/util/errors"
|
||||
)
|
||||
|
||||
// Error is an implementation of the 'error' interface, which represents a
|
||||
// field-level validation error.
|
||||
type Error struct {
|
||||
Type ErrorType
|
||||
Field string
|
||||
BadValue interface{}
|
||||
Detail string
|
||||
}
|
||||
|
||||
var _ error = &Error{}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (v *Error) Error() string {
|
||||
return fmt.Sprintf("%s: %s", v.Field, v.ErrorBody())
|
||||
}
|
||||
|
||||
// ErrorBody returns the error message without the field name. This is useful
|
||||
// for building nice-looking higher-level error reporting.
|
||||
func (v *Error) ErrorBody() string {
|
||||
var s string
|
||||
switch v.Type {
|
||||
case ErrorTypeRequired, ErrorTypeForbidden, ErrorTypeTooLong, ErrorTypeInternal:
|
||||
s = fmt.Sprintf("%s", v.Type)
|
||||
default:
|
||||
var bad string
|
||||
badBytes, err := json.Marshal(v.BadValue)
|
||||
if err != nil {
|
||||
bad = err.Error()
|
||||
} else {
|
||||
bad = string(badBytes)
|
||||
}
|
||||
s = fmt.Sprintf("%s: %s", v.Type, bad)
|
||||
}
|
||||
if len(v.Detail) != 0 {
|
||||
s += fmt.Sprintf(": %s", v.Detail)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// ErrorType is a machine readable value providing more detail about why
|
||||
// a field is invalid. These values are expected to match 1-1 with
|
||||
// CauseType in api/types.go.
|
||||
type ErrorType string
|
||||
|
||||
// TODO: These values are duplicated in api/types.go, but there's a circular dep. Fix it.
|
||||
const (
|
||||
// ErrorTypeNotFound is used to report failure to find a requested value
|
||||
// (e.g. looking up an ID). See NotFound().
|
||||
ErrorTypeNotFound ErrorType = "FieldValueNotFound"
|
||||
// ErrorTypeRequired is used to report required values that are not
|
||||
// provided (e.g. empty strings, null values, or empty arrays). See
|
||||
// Required().
|
||||
ErrorTypeRequired ErrorType = "FieldValueRequired"
|
||||
// ErrorTypeDuplicate is used to report collisions of values that must be
|
||||
// unique (e.g. unique IDs). See Duplicate().
|
||||
ErrorTypeDuplicate ErrorType = "FieldValueDuplicate"
|
||||
// ErrorTypeInvalid is used to report malformed values (e.g. failed regex
|
||||
// match, too long, out of bounds). See Invalid().
|
||||
ErrorTypeInvalid ErrorType = "FieldValueInvalid"
|
||||
// ErrorTypeNotSupported is used to report unknown values for enumerated
|
||||
// fields (e.g. a list of valid values). See NotSupported().
|
||||
ErrorTypeNotSupported ErrorType = "FieldValueNotSupported"
|
||||
// ErrorTypeForbidden is used to report valid (as per formatting rules)
|
||||
// values which would be accepted under some conditions, but which are not
|
||||
// permitted by the current conditions (such as security policy). See
|
||||
// Forbidden().
|
||||
ErrorTypeForbidden ErrorType = "FieldValueForbidden"
|
||||
// ErrorTypeTooLong is used to report that the given value is too long.
|
||||
// This is similar to ErrorTypeInvalid, but the error will not include the
|
||||
// too-long value. See TooLong().
|
||||
ErrorTypeTooLong ErrorType = "FieldValueTooLong"
|
||||
// ErrorTypeInternal is used to report other errors that are not related
|
||||
// to user input. See InternalError().
|
||||
ErrorTypeInternal ErrorType = "InternalError"
|
||||
)
|
||||
|
||||
// String converts a ErrorType into its corresponding canonical error message.
|
||||
func (t ErrorType) String() string {
|
||||
switch t {
|
||||
case ErrorTypeNotFound:
|
||||
return "Not found"
|
||||
case ErrorTypeRequired:
|
||||
return "Required value"
|
||||
case ErrorTypeDuplicate:
|
||||
return "Duplicate value"
|
||||
case ErrorTypeInvalid:
|
||||
return "Invalid value"
|
||||
case ErrorTypeNotSupported:
|
||||
return "Unsupported value"
|
||||
case ErrorTypeForbidden:
|
||||
return "Forbidden"
|
||||
case ErrorTypeTooLong:
|
||||
return "Too long"
|
||||
case ErrorTypeInternal:
|
||||
return "Internal error"
|
||||
default:
|
||||
panic(fmt.Sprintf("unrecognized validation error: %q", string(t)))
|
||||
}
|
||||
}
|
||||
|
||||
// NotFound returns a *Error indicating "value not found". This is
|
||||
// used to report failure to find a requested value (e.g. looking up an ID).
|
||||
func NotFound(field *Path, value interface{}) *Error {
|
||||
return &Error{ErrorTypeNotFound, field.String(), value, ""}
|
||||
}
|
||||
|
||||
// Required returns a *Error indicating "value required". This is used
|
||||
// to report required values that are not provided (e.g. empty strings, null
|
||||
// values, or empty arrays).
|
||||
func Required(field *Path, detail string) *Error {
|
||||
return &Error{ErrorTypeRequired, field.String(), "", detail}
|
||||
}
|
||||
|
||||
// Duplicate returns a *Error indicating "duplicate value". This is
|
||||
// used to report collisions of values that must be unique (e.g. names or IDs).
|
||||
func Duplicate(field *Path, value interface{}) *Error {
|
||||
return &Error{ErrorTypeDuplicate, field.String(), value, ""}
|
||||
}
|
||||
|
||||
// Invalid returns a *Error indicating "invalid value". This is used
|
||||
// to report malformed values (e.g. failed regex match, too long, out of bounds).
|
||||
func Invalid(field *Path, value interface{}, detail string) *Error {
|
||||
return &Error{ErrorTypeInvalid, field.String(), value, detail}
|
||||
}
|
||||
|
||||
// NotSupported returns a *Error indicating "unsupported value".
|
||||
// This is used to report unknown values for enumerated fields (e.g. a list of
|
||||
// valid values).
|
||||
func NotSupported(field *Path, value interface{}, validValues []string) *Error {
|
||||
detail := ""
|
||||
if validValues != nil && len(validValues) > 0 {
|
||||
detail = "supported values: " + strings.Join(validValues, ", ")
|
||||
}
|
||||
return &Error{ErrorTypeNotSupported, field.String(), value, detail}
|
||||
}
|
||||
|
||||
// Forbidden returns a *Error indicating "forbidden". This is used to
|
||||
// report valid (as per formatting rules) values which would be accepted under
|
||||
// some conditions, but which are not permitted by current conditions (e.g.
|
||||
// security policy).
|
||||
func Forbidden(field *Path, detail string) *Error {
|
||||
return &Error{ErrorTypeForbidden, field.String(), "", detail}
|
||||
}
|
||||
|
||||
// TooLong returns a *Error indicating "too long". This is used to
|
||||
// report that the given value is too long. This is similar to
|
||||
// Invalid, but the returned error will not include the too-long
|
||||
// value.
|
||||
func TooLong(field *Path, value interface{}, maxLength int) *Error {
|
||||
return &Error{ErrorTypeTooLong, field.String(), value, fmt.Sprintf("must have at most %d characters", maxLength)}
|
||||
}
|
||||
|
||||
// InternalError returns a *Error indicating "internal error". This is used
|
||||
// to signal that an error was found that was not directly related to user
|
||||
// input. The err argument must be non-nil.
|
||||
func InternalError(field *Path, err error) *Error {
|
||||
return &Error{ErrorTypeInternal, field.String(), nil, err.Error()}
|
||||
}
|
||||
|
||||
// ErrorList holds a set of Errors. It is plausible that we might one day have
|
||||
// non-field errors in this same umbrella package, but for now we don't, so
|
||||
// we can keep it simple and leave ErrorList here.
|
||||
type ErrorList []*Error
|
||||
|
||||
// NewErrorTypeMatcher returns an errors.Matcher that returns true
|
||||
// if the provided error is a Error and has the provided ErrorType.
|
||||
func NewErrorTypeMatcher(t ErrorType) utilerrors.Matcher {
|
||||
return func(err error) bool {
|
||||
if e, ok := err.(*Error); ok {
|
||||
return e.Type == t
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ToAggregate converts the ErrorList into an errors.Aggregate.
|
||||
func (list ErrorList) ToAggregate() utilerrors.Aggregate {
|
||||
errs := make([]error, len(list))
|
||||
for i := range list {
|
||||
errs[i] = list[i]
|
||||
}
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
func fromAggregate(agg utilerrors.Aggregate) ErrorList {
|
||||
errs := agg.Errors()
|
||||
list := make(ErrorList, len(errs))
|
||||
for i := range errs {
|
||||
list[i] = errs[i].(*Error)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// Filter removes items from the ErrorList that match the provided fns.
|
||||
func (list ErrorList) Filter(fns ...utilerrors.Matcher) ErrorList {
|
||||
err := utilerrors.FilterOut(list.ToAggregate(), fns...)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
// FilterOut takes an Aggregate and returns an Aggregate
|
||||
return fromAggregate(err.(utilerrors.Aggregate))
|
||||
}
|
91
vendor/k8s.io/client-go/1.5/pkg/util/validation/field/path.go
generated
vendored
Normal file
91
vendor/k8s.io/client-go/1.5/pkg/util/validation/field/path.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Copyright 2015 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 field
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Path represents the path from some root to a particular field.
|
||||
type Path struct {
|
||||
name string // the name of this field or "" if this is an index
|
||||
index string // if name == "", this is a subscript (index or map key) of the previous element
|
||||
parent *Path // nil if this is the root element
|
||||
}
|
||||
|
||||
// NewPath creates a root Path object.
|
||||
func NewPath(name string, moreNames ...string) *Path {
|
||||
r := &Path{name: name, parent: nil}
|
||||
for _, anotherName := range moreNames {
|
||||
r = &Path{name: anotherName, parent: r}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Root returns the root element of this Path.
|
||||
func (p *Path) Root() *Path {
|
||||
for ; p.parent != nil; p = p.parent {
|
||||
// Do nothing.
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Child creates a new Path that is a child of the method receiver.
|
||||
func (p *Path) Child(name string, moreNames ...string) *Path {
|
||||
r := NewPath(name, moreNames...)
|
||||
r.Root().parent = p
|
||||
return r
|
||||
}
|
||||
|
||||
// Index indicates that the previous Path is to be subscripted by an int.
|
||||
// This sets the same underlying value as Key.
|
||||
func (p *Path) Index(index int) *Path {
|
||||
return &Path{index: strconv.Itoa(index), parent: p}
|
||||
}
|
||||
|
||||
// Key indicates that the previous Path is to be subscripted by a string.
|
||||
// This sets the same underlying value as Index.
|
||||
func (p *Path) Key(key string) *Path {
|
||||
return &Path{index: key, parent: p}
|
||||
}
|
||||
|
||||
// String produces a string representation of the Path.
|
||||
func (p *Path) String() string {
|
||||
// make a slice to iterate
|
||||
elems := []*Path{}
|
||||
for ; p != nil; p = p.parent {
|
||||
elems = append(elems, p)
|
||||
}
|
||||
|
||||
// iterate, but it has to be backwards
|
||||
buf := bytes.NewBuffer(nil)
|
||||
for i := range elems {
|
||||
p := elems[len(elems)-1-i]
|
||||
if p.parent != nil && len(p.name) > 0 {
|
||||
// This is either the root or it is a subscript.
|
||||
buf.WriteString(".")
|
||||
}
|
||||
if len(p.name) > 0 {
|
||||
buf.WriteString(p.name)
|
||||
} else {
|
||||
fmt.Fprintf(buf, "[%s]", p.index)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
334
vendor/k8s.io/client-go/1.5/pkg/util/validation/validation.go
generated
vendored
Normal file
334
vendor/k8s.io/client-go/1.5/pkg/util/validation/validation.go
generated
vendored
Normal file
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const qnameCharFmt string = "[A-Za-z0-9]"
|
||||
const qnameExtCharFmt string = "[-A-Za-z0-9_.]"
|
||||
const qualifiedNameFmt string = "(" + qnameCharFmt + qnameExtCharFmt + "*)?" + qnameCharFmt
|
||||
const qualifiedNameMaxLength int = 63
|
||||
|
||||
var qualifiedNameRegexp = regexp.MustCompile("^" + qualifiedNameFmt + "$")
|
||||
|
||||
// IsQualifiedName tests whether the value passed is what Kubernetes calls a
|
||||
// "qualified name". This is a format used in various places throughout the
|
||||
// system. If the value is not valid, a list of error strings is returned.
|
||||
// Otherwise an empty list (or nil) is returned.
|
||||
func IsQualifiedName(value string) []string {
|
||||
var errs []string
|
||||
parts := strings.Split(value, "/")
|
||||
var name string
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
name = parts[0]
|
||||
case 2:
|
||||
var prefix string
|
||||
prefix, name = parts[0], parts[1]
|
||||
if len(prefix) == 0 {
|
||||
errs = append(errs, "prefix part "+EmptyError())
|
||||
} else if msgs := IsDNS1123Subdomain(prefix); len(msgs) != 0 {
|
||||
errs = append(errs, prefixEach(msgs, "prefix part ")...)
|
||||
}
|
||||
default:
|
||||
return append(errs, RegexError(qualifiedNameFmt, "MyName", "my.name", "123-abc")+
|
||||
" with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName'")
|
||||
}
|
||||
|
||||
if len(name) == 0 {
|
||||
errs = append(errs, "name part "+EmptyError())
|
||||
} else if len(name) > qualifiedNameMaxLength {
|
||||
errs = append(errs, "name part "+MaxLenError(qualifiedNameMaxLength))
|
||||
}
|
||||
if !qualifiedNameRegexp.MatchString(name) {
|
||||
errs = append(errs, "name part "+RegexError(qualifiedNameFmt, "MyName", "my.name", "123-abc"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
const labelValueFmt string = "(" + qualifiedNameFmt + ")?"
|
||||
const LabelValueMaxLength int = 63
|
||||
|
||||
var labelValueRegexp = regexp.MustCompile("^" + labelValueFmt + "$")
|
||||
|
||||
// IsValidLabelValue tests whether the value passed is a valid label value. If
|
||||
// the value is not valid, a list of error strings is returned. Otherwise an
|
||||
// empty list (or nil) is returned.
|
||||
func IsValidLabelValue(value string) []string {
|
||||
var errs []string
|
||||
if len(value) > LabelValueMaxLength {
|
||||
errs = append(errs, MaxLenError(LabelValueMaxLength))
|
||||
}
|
||||
if !labelValueRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(labelValueFmt, "MyValue", "my_value", "12345"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
const dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
|
||||
const DNS1123LabelMaxLength int = 63
|
||||
|
||||
var dns1123LabelRegexp = regexp.MustCompile("^" + dns1123LabelFmt + "$")
|
||||
|
||||
// IsDNS1123Label tests for a string that conforms to the definition of a label in
|
||||
// DNS (RFC 1123).
|
||||
func IsDNS1123Label(value string) []string {
|
||||
var errs []string
|
||||
if len(value) > DNS1123LabelMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1123LabelMaxLength))
|
||||
}
|
||||
if !dns1123LabelRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(dns1123LabelFmt, "my-name", "123-abc"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"
|
||||
const DNS1123SubdomainMaxLength int = 253
|
||||
|
||||
var dns1123SubdomainRegexp = regexp.MustCompile("^" + dns1123SubdomainFmt + "$")
|
||||
|
||||
// IsDNS1123Subdomain tests for a string that conforms to the definition of a
|
||||
// subdomain in DNS (RFC 1123).
|
||||
func IsDNS1123Subdomain(value string) []string {
|
||||
var errs []string
|
||||
if len(value) > DNS1123SubdomainMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
|
||||
}
|
||||
if !dns1123SubdomainRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(dns1123SubdomainFmt, "example.com"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
|
||||
const DNS1035LabelMaxLength int = 63
|
||||
|
||||
var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$")
|
||||
|
||||
// IsDNS1035Label tests for a string that conforms to the definition of a label in
|
||||
// DNS (RFC 1035).
|
||||
func IsDNS1035Label(value string) []string {
|
||||
var errs []string
|
||||
if len(value) > DNS1035LabelMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1035LabelMaxLength))
|
||||
}
|
||||
if !dns1035LabelRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(dns1035LabelFmt, "my-name", "abc-123"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// wildcard definition - RFC 1034 section 4.3.3.
|
||||
// examples:
|
||||
// - valid: *.bar.com, *.foo.bar.com
|
||||
// - invalid: *.*.bar.com, *.foo.*.com, *bar.com, f*.bar.com, *
|
||||
const wildcardDNF1123SubdomainFmt = "\\*\\." + dns1123SubdomainFmt
|
||||
|
||||
// IsWildcardDNS1123Subdomain tests for a string that conforms to the definition of a
|
||||
// wildcard subdomain in DNS (RFC 1034 section 4.3.3).
|
||||
func IsWildcardDNS1123Subdomain(value string) []string {
|
||||
wildcardDNS1123SubdomainRegexp := regexp.MustCompile("^\\*\\." + dns1123SubdomainFmt + "$")
|
||||
|
||||
var errs []string
|
||||
if len(value) > DNS1123SubdomainMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
|
||||
}
|
||||
if !wildcardDNS1123SubdomainRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(wildcardDNF1123SubdomainFmt, "*.example.com"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
const cIdentifierFmt string = "[A-Za-z_][A-Za-z0-9_]*"
|
||||
|
||||
var cIdentifierRegexp = regexp.MustCompile("^" + cIdentifierFmt + "$")
|
||||
|
||||
// IsCIdentifier tests for a string that conforms the definition of an identifier
|
||||
// in C. This checks the format, but not the length.
|
||||
func IsCIdentifier(value string) []string {
|
||||
if !cIdentifierRegexp.MatchString(value) {
|
||||
return []string{RegexError(cIdentifierFmt, "my_name", "MY_NAME", "MyName")}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsValidPortNum tests that the argument is a valid, non-zero port number.
|
||||
func IsValidPortNum(port int) []string {
|
||||
if 1 <= port && port <= 65535 {
|
||||
return nil
|
||||
}
|
||||
return []string{InclusiveRangeError(1, 65535)}
|
||||
}
|
||||
|
||||
// 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 (
|
||||
minUserID = 0
|
||||
maxUserID = math.MaxInt32
|
||||
minGroupID = 0
|
||||
maxGroupID = math.MaxInt32
|
||||
)
|
||||
|
||||
// IsValidGroupId tests that the argument is a valid Unix GID.
|
||||
func IsValidGroupId(gid int64) []string {
|
||||
if minGroupID <= gid && gid <= maxGroupID {
|
||||
return nil
|
||||
}
|
||||
return []string{InclusiveRangeError(minGroupID, maxGroupID)}
|
||||
}
|
||||
|
||||
// IsValidUserId tests that the argument is a valid Unix UID.
|
||||
func IsValidUserId(uid int64) []string {
|
||||
if minUserID <= uid && uid <= maxUserID {
|
||||
return nil
|
||||
}
|
||||
return []string{InclusiveRangeError(minUserID, maxUserID)}
|
||||
}
|
||||
|
||||
var portNameCharsetRegex = regexp.MustCompile("^[-a-z0-9]+$")
|
||||
var portNameOneLetterRegexp = regexp.MustCompile("[a-z]")
|
||||
|
||||
// IsValidPortName check that the argument is valid syntax. It must be
|
||||
// non-empty and no more than 15 characters long. It may contain only [-a-z0-9]
|
||||
// and must contain at least one letter [a-z]. It must not start or end with a
|
||||
// hyphen, nor contain adjacent hyphens.
|
||||
//
|
||||
// Note: We only allow lower-case characters, even though RFC 6335 is case
|
||||
// insensitive.
|
||||
func IsValidPortName(port string) []string {
|
||||
var errs []string
|
||||
if len(port) > 15 {
|
||||
errs = append(errs, MaxLenError(15))
|
||||
}
|
||||
if !portNameCharsetRegex.MatchString(port) {
|
||||
errs = append(errs, "must contain only alpha-numeric characters (a-z, 0-9), and hyphens (-)")
|
||||
}
|
||||
if !portNameOneLetterRegexp.MatchString(port) {
|
||||
errs = append(errs, "must contain at least one letter (a-z)")
|
||||
}
|
||||
if strings.Contains(port, "--") {
|
||||
errs = append(errs, "must not contain consecutive hyphens")
|
||||
}
|
||||
if len(port) > 0 && (port[0] == '-' || port[len(port)-1] == '-') {
|
||||
errs = append(errs, "must not begin or end with a hyphen")
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// IsValidIP tests that the argument is a valid IP address.
|
||||
func IsValidIP(value string) []string {
|
||||
if net.ParseIP(value) == nil {
|
||||
return []string{"must be a valid IP address, (e.g. 10.9.8.7)"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const percentFmt string = "[0-9]+%"
|
||||
|
||||
var percentRegexp = regexp.MustCompile("^" + percentFmt + "$")
|
||||
|
||||
func IsValidPercent(percent string) []string {
|
||||
if !percentRegexp.MatchString(percent) {
|
||||
return []string{RegexError(percentFmt, "1%", "93%")}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const httpHeaderNameFmt string = "[-A-Za-z0-9]+"
|
||||
|
||||
var httpHeaderNameRegexp = regexp.MustCompile("^" + httpHeaderNameFmt + "$")
|
||||
|
||||
// IsHTTPHeaderName checks that a string conforms to the Go HTTP library's
|
||||
// definition of a valid header field name (a stricter subset than RFC7230).
|
||||
func IsHTTPHeaderName(value string) []string {
|
||||
if !httpHeaderNameRegexp.MatchString(value) {
|
||||
return []string{RegexError(httpHeaderNameFmt, "X-Header-Name")}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const configMapKeyFmt = `[-._a-zA-Z0-9]+`
|
||||
|
||||
var configMapKeyRegexp = regexp.MustCompile("^" + configMapKeyFmt + "$")
|
||||
|
||||
// IsConfigMapKey tests for a string that is a valid key for a ConfigMap or Secret
|
||||
func IsConfigMapKey(value string) []string {
|
||||
var errs []string
|
||||
if len(value) > DNS1123SubdomainMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
|
||||
}
|
||||
if !configMapKeyRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(configMapKeyFmt, "key.name", "KEY_NAME", "key-name"))
|
||||
}
|
||||
if value == "." {
|
||||
errs = append(errs, `must not be '.'`)
|
||||
}
|
||||
if value == ".." {
|
||||
errs = append(errs, `must not be '..'`)
|
||||
} else if strings.HasPrefix(value, "..") {
|
||||
errs = append(errs, `must not start with '..'`)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// MaxLenError returns a string explanation of a "string too long" validation
|
||||
// failure.
|
||||
func MaxLenError(length int) string {
|
||||
return fmt.Sprintf("must be no more than %d characters", length)
|
||||
}
|
||||
|
||||
// RegexError returns a string explanation of a regex validation failure.
|
||||
func RegexError(fmt string, examples ...string) string {
|
||||
s := "must match the regex " + fmt
|
||||
if len(examples) == 0 {
|
||||
return s
|
||||
}
|
||||
s += " (e.g. "
|
||||
for i := range examples {
|
||||
if i > 0 {
|
||||
s += " or "
|
||||
}
|
||||
s += "'" + examples[i] + "'"
|
||||
}
|
||||
return s + ")"
|
||||
}
|
||||
|
||||
// EmptyError returns a string explanation of a "must not be empty" validation
|
||||
// failure.
|
||||
func EmptyError() string {
|
||||
return "must be non-empty"
|
||||
}
|
||||
|
||||
func prefixEach(msgs []string, prefix string) []string {
|
||||
for i := range msgs {
|
||||
msgs[i] = prefix + msgs[i]
|
||||
}
|
||||
return msgs
|
||||
}
|
||||
|
||||
// InclusiveRangeError returns a string explanation of a numeric "must be
|
||||
// between" validation failure.
|
||||
func InclusiveRangeError(lo, hi int) string {
|
||||
return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi)
|
||||
}
|
19
vendor/k8s.io/client-go/1.5/pkg/util/wait/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/client-go/1.5/pkg/util/wait/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
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 wait provides tools for polling or listening for changes
|
||||
// to a condition.
|
||||
package wait
|
268
vendor/k8s.io/client-go/1.5/pkg/util/wait/wait.go
generated
vendored
Normal file
268
vendor/k8s.io/client-go/1.5/pkg/util/wait/wait.go
generated
vendored
Normal file
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
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 wait
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
// For any test of the style:
|
||||
// ...
|
||||
// <- time.After(timeout):
|
||||
// t.Errorf("Timed out")
|
||||
// The value for timeout should effectively be "forever." Obviously we don't want our tests to truly lock up forever, but 30s
|
||||
// is long enough that it is effectively forever for the things that can slow down a run on a heavily contended machine
|
||||
// (GC, seeks, etc), but not so long as to make a developer ctrl-c a test run if they do happen to break that test.
|
||||
var ForeverTestTimeout = time.Second * 30
|
||||
|
||||
// NeverStop may be passed to Until to make it never stop.
|
||||
var NeverStop <-chan struct{} = make(chan struct{})
|
||||
|
||||
// Forever is syntactic sugar on top of Until
|
||||
func Forever(f func(), period time.Duration) {
|
||||
Until(f, period, NeverStop)
|
||||
}
|
||||
|
||||
// Until loops until stop channel is closed, running f every period.
|
||||
// Until is syntactic sugar on top of JitterUntil with zero jitter
|
||||
// factor, with sliding = true (which means the timer for period
|
||||
// starts after the f completes).
|
||||
func Until(f func(), period time.Duration, stopCh <-chan struct{}) {
|
||||
JitterUntil(f, period, 0.0, true, stopCh)
|
||||
}
|
||||
|
||||
// NonSlidingUntil loops until stop channel is closed, running f every
|
||||
// period. NonSlidingUntil is syntactic sugar on top of JitterUntil
|
||||
// with zero jitter factor, with sliding = false (meaning the timer for
|
||||
// period starts at the same time as the function starts).
|
||||
func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) {
|
||||
JitterUntil(f, period, 0.0, false, stopCh)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Catches any panics, and keeps going. f may not be invoked if
|
||||
// stop channel is already closed. Pass NeverStop to Until if you
|
||||
// don't want it stop.
|
||||
func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) {
|
||||
for {
|
||||
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
jitteredPeriod := period
|
||||
if jitterFactor > 0.0 {
|
||||
jitteredPeriod = Jitter(period, jitterFactor)
|
||||
}
|
||||
|
||||
var t *time.Timer
|
||||
if !sliding {
|
||||
t = time.NewTimer(jitteredPeriod)
|
||||
}
|
||||
|
||||
func() {
|
||||
f()
|
||||
}()
|
||||
|
||||
if sliding {
|
||||
t = time.NewTimer(jitteredPeriod)
|
||||
}
|
||||
|
||||
// NOTE: b/c there is no priority selection in golang
|
||||
// it is possible for this to race, meaning we could
|
||||
// trigger t.C and stopCh, and t.C select falls through.
|
||||
// In order to mitigate we re-check stopCh at the beginning
|
||||
// of every loop to prevent extra executions of f().
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
case <-t.C:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Jitter returns a time.Duration between duration and duration + maxFactor * duration,
|
||||
// to allow clients to avoid converging on periodic behavior. If maxFactor is 0.0, a
|
||||
// suggested default value will be chosen.
|
||||
func Jitter(duration time.Duration, maxFactor float64) time.Duration {
|
||||
if maxFactor <= 0.0 {
|
||||
maxFactor = 1.0
|
||||
}
|
||||
wait := duration + time.Duration(rand.Float64()*maxFactor*float64(duration))
|
||||
return wait
|
||||
}
|
||||
|
||||
// ErrWaitTimeout is returned when the condition exited without success
|
||||
var ErrWaitTimeout = errors.New("timed out waiting for the condition")
|
||||
|
||||
// ConditionFunc returns true if the condition is satisfied, or an error
|
||||
// if the loop should be aborted.
|
||||
type ConditionFunc func() (done bool, err error)
|
||||
|
||||
// Backoff is parameters applied to a Backoff function.
|
||||
type Backoff struct {
|
||||
Duration time.Duration
|
||||
Factor float64
|
||||
Jitter float64
|
||||
Steps int
|
||||
}
|
||||
|
||||
// ExponentialBackoff repeats a condition check up to steps times, increasing the wait
|
||||
// by multipling the previous duration by factor. If jitter is greater than zero,
|
||||
// a random amount of each duration is added (between duration and duration*(1+jitter)).
|
||||
// If the condition never returns true, ErrWaitTimeout is returned. All other errors
|
||||
// terminate immediately.
|
||||
func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error {
|
||||
duration := backoff.Duration
|
||||
for i := 0; i < backoff.Steps; i++ {
|
||||
if i != 0 {
|
||||
adjusted := duration
|
||||
if backoff.Jitter > 0.0 {
|
||||
adjusted = Jitter(duration, backoff.Jitter)
|
||||
}
|
||||
time.Sleep(adjusted)
|
||||
duration = time.Duration(float64(duration) * backoff.Factor)
|
||||
}
|
||||
if ok, err := condition(); err != nil || ok {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return ErrWaitTimeout
|
||||
}
|
||||
|
||||
// Poll tries a condition func until it returns true, an error, or the timeout
|
||||
// is reached. condition will always be invoked at least once but some intervals
|
||||
// may be missed if the condition takes too long or the time window is too short.
|
||||
// If you want to Poll something forever, see PollInfinite.
|
||||
// Poll always waits the interval before the first check of the condition.
|
||||
func Poll(interval, timeout time.Duration, condition ConditionFunc) error {
|
||||
return pollInternal(poller(interval, timeout), condition)
|
||||
}
|
||||
|
||||
func pollInternal(wait WaitFunc, condition ConditionFunc) error {
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
return WaitFor(wait, condition, done)
|
||||
}
|
||||
|
||||
// PollImmediate is identical to Poll, except that it performs the first check
|
||||
// immediately, not waiting interval beforehand.
|
||||
func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error {
|
||||
return pollImmediateInternal(poller(interval, timeout), condition)
|
||||
}
|
||||
|
||||
func pollImmediateInternal(wait WaitFunc, condition ConditionFunc) error {
|
||||
done, err := condition()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
return nil
|
||||
}
|
||||
return pollInternal(wait, condition)
|
||||
}
|
||||
|
||||
// PollInfinite polls forever.
|
||||
func PollInfinite(interval time.Duration, condition ConditionFunc) error {
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
return PollUntil(interval, condition, done)
|
||||
}
|
||||
|
||||
// PollUntil is like Poll, but it takes a stop change instead of total duration
|
||||
func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
|
||||
return WaitFor(poller(interval, 0), condition, stopCh)
|
||||
}
|
||||
|
||||
// WaitFunc creates a channel that receives an item every time a test
|
||||
// should be executed and is closed when the last test should be invoked.
|
||||
type WaitFunc func(done <-chan struct{}) <-chan struct{}
|
||||
|
||||
// WaitFor gets a channel from wait(), and then invokes fn once for every value
|
||||
// placed on the channel and once more when the channel is closed. If fn
|
||||
// returns an error the loop ends and that error is returned, and if fn returns
|
||||
// true the loop ends and nil is returned. ErrWaitTimeout will be returned if
|
||||
// the channel is closed without fn ever returning true.
|
||||
func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error {
|
||||
c := wait(done)
|
||||
for {
|
||||
_, open := <-c
|
||||
ok, err := fn()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
if !open {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ErrWaitTimeout
|
||||
}
|
||||
|
||||
// poller returns a WaitFunc that will send to the channel every
|
||||
// interval until timeout has elapsed and then close the channel.
|
||||
// Over very short intervals you may receive no ticks before
|
||||
// the channel is closed. If timeout is 0, the channel
|
||||
// will never be closed.
|
||||
func poller(interval, timeout time.Duration) WaitFunc {
|
||||
return WaitFunc(func(done <-chan struct{}) <-chan struct{} {
|
||||
ch := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
defer close(ch)
|
||||
|
||||
tick := time.NewTicker(interval)
|
||||
defer tick.Stop()
|
||||
|
||||
var after <-chan time.Time
|
||||
if timeout != 0 {
|
||||
// time.After is more convenient, but it
|
||||
// potentially leaves timers around much longer
|
||||
// than necessary if we exit early.
|
||||
timer := time.NewTimer(timeout)
|
||||
after = timer.C
|
||||
defer timer.Stop()
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
// If the consumer isn't ready for this signal drop it and
|
||||
// check the other channels.
|
||||
select {
|
||||
case ch <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
case <-after:
|
||||
return
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return ch
|
||||
})
|
||||
}
|
306
vendor/k8s.io/client-go/1.5/pkg/util/yaml/decoder.go
generated
vendored
Normal file
306
vendor/k8s.io/client-go/1.5/pkg/util/yaml/decoder.go
generated
vendored
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
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 yaml
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// ToJSON converts a single YAML document into a JSON document
|
||||
// or returns an error. If the document appears to be JSON the
|
||||
// YAML decoding path is not used (so that error messages are
|
||||
// JSON specific).
|
||||
func ToJSON(data []byte) ([]byte, error) {
|
||||
if hasJSONPrefix(data) {
|
||||
return data, nil
|
||||
}
|
||||
return yaml.YAMLToJSON(data)
|
||||
}
|
||||
|
||||
// YAMLToJSONDecoder decodes YAML documents from an io.Reader by
|
||||
// separating individual documents. It first converts the YAML
|
||||
// body to JSON, then unmarshals the JSON.
|
||||
type YAMLToJSONDecoder struct {
|
||||
reader Reader
|
||||
}
|
||||
|
||||
// NewYAMLToJSONDecoder decodes YAML documents from the provided
|
||||
// stream in chunks by converting each document (as defined by
|
||||
// the YAML spec) into its own chunk, converting it to JSON via
|
||||
// yaml.YAMLToJSON, and then passing it to json.Decoder.
|
||||
func NewYAMLToJSONDecoder(r io.Reader) *YAMLToJSONDecoder {
|
||||
reader := bufio.NewReader(r)
|
||||
return &YAMLToJSONDecoder{
|
||||
reader: NewYAMLReader(reader),
|
||||
}
|
||||
}
|
||||
|
||||
// Decode reads a YAML document as JSON from the stream or returns
|
||||
// an error. The decoding rules match json.Unmarshal, not
|
||||
// yaml.Unmarshal.
|
||||
func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
||||
bytes, err := d.reader.Read()
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(bytes) != 0 {
|
||||
data, err := yaml.YAMLToJSON(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(data, into)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// YAMLDecoder reads chunks of objects and returns ErrShortBuffer if
|
||||
// the data is not sufficient.
|
||||
type YAMLDecoder struct {
|
||||
r io.ReadCloser
|
||||
scanner *bufio.Scanner
|
||||
remaining []byte
|
||||
}
|
||||
|
||||
// NewDocumentDecoder decodes YAML documents from the provided
|
||||
// stream in chunks by converting each document (as defined by
|
||||
// the YAML spec) into its own chunk. io.ErrShortBuffer will be
|
||||
// returned if the entire buffer could not be read to assist
|
||||
// the caller in framing the chunk.
|
||||
func NewDocumentDecoder(r io.ReadCloser) io.ReadCloser {
|
||||
scanner := bufio.NewScanner(r)
|
||||
scanner.Split(splitYAMLDocument)
|
||||
return &YAMLDecoder{
|
||||
r: r,
|
||||
scanner: scanner,
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads the previous slice into the buffer, or attempts to read
|
||||
// the next chunk.
|
||||
// TODO: switch to readline approach.
|
||||
func (d *YAMLDecoder) Read(data []byte) (n int, err error) {
|
||||
left := len(d.remaining)
|
||||
if left == 0 {
|
||||
// return the next chunk from the stream
|
||||
if !d.scanner.Scan() {
|
||||
err := d.scanner.Err()
|
||||
if err == nil {
|
||||
err = io.EOF
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
out := d.scanner.Bytes()
|
||||
d.remaining = out
|
||||
left = len(out)
|
||||
}
|
||||
|
||||
// fits within data
|
||||
if left <= len(data) {
|
||||
copy(data, d.remaining)
|
||||
d.remaining = nil
|
||||
return len(d.remaining), nil
|
||||
}
|
||||
|
||||
// caller will need to reread
|
||||
copy(data, d.remaining[:left])
|
||||
d.remaining = d.remaining[left:]
|
||||
return len(data), io.ErrShortBuffer
|
||||
}
|
||||
|
||||
func (d *YAMLDecoder) Close() error {
|
||||
return d.r.Close()
|
||||
}
|
||||
|
||||
const yamlSeparator = "\n---"
|
||||
const separator = "---\n"
|
||||
|
||||
// splitYAMLDocument is a bufio.SplitFunc for splitting YAML streams into individual documents.
|
||||
func splitYAMLDocument(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
if atEOF && len(data) == 0 {
|
||||
return 0, nil, nil
|
||||
}
|
||||
sep := len([]byte(yamlSeparator))
|
||||
if i := bytes.Index(data, []byte(yamlSeparator)); i >= 0 {
|
||||
// We have a potential document terminator
|
||||
i += sep
|
||||
after := data[i:]
|
||||
if len(after) == 0 {
|
||||
// we can't read any more characters
|
||||
if atEOF {
|
||||
return len(data), data[:len(data)-sep], nil
|
||||
}
|
||||
return 0, nil, nil
|
||||
}
|
||||
if j := bytes.IndexByte(after, '\n'); j >= 0 {
|
||||
return i + j + 1, data[0 : i-sep], nil
|
||||
}
|
||||
return 0, nil, nil
|
||||
}
|
||||
// If we're at EOF, we have a final, non-terminated line. Return it.
|
||||
if atEOF {
|
||||
return len(data), data, nil
|
||||
}
|
||||
// Request more data.
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
// decoder is a convenience interface for Decode.
|
||||
type decoder interface {
|
||||
Decode(into interface{}) error
|
||||
}
|
||||
|
||||
// YAMLOrJSONDecoder attempts to decode a stream of JSON documents or
|
||||
// YAML documents by sniffing for a leading { character.
|
||||
type YAMLOrJSONDecoder struct {
|
||||
r io.Reader
|
||||
bufferSize int
|
||||
|
||||
decoder decoder
|
||||
}
|
||||
|
||||
// NewYAMLOrJSONDecoder returns a decoder that will process YAML documents
|
||||
// or JSON documents from the given reader as a stream. bufferSize determines
|
||||
// how far into the stream the decoder will look to figure out whether this
|
||||
// is a JSON stream (has whitespace followed by an open brace).
|
||||
func NewYAMLOrJSONDecoder(r io.Reader, bufferSize int) *YAMLOrJSONDecoder {
|
||||
return &YAMLOrJSONDecoder{
|
||||
r: r,
|
||||
bufferSize: bufferSize,
|
||||
}
|
||||
}
|
||||
|
||||
// Decode unmarshals the next object from the underlying stream into the
|
||||
// provide object, or returns an error.
|
||||
func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
|
||||
if d.decoder == nil {
|
||||
buffer, isJSON := GuessJSONStream(d.r, d.bufferSize)
|
||||
if isJSON {
|
||||
glog.V(4).Infof("decoding stream as JSON")
|
||||
d.decoder = json.NewDecoder(buffer)
|
||||
} else {
|
||||
glog.V(4).Infof("decoding stream as YAML")
|
||||
d.decoder = NewYAMLToJSONDecoder(buffer)
|
||||
}
|
||||
}
|
||||
err := d.decoder.Decode(into)
|
||||
if jsonDecoder, ok := d.decoder.(*json.Decoder); ok {
|
||||
if syntax, ok := err.(*json.SyntaxError); ok {
|
||||
data, readErr := ioutil.ReadAll(jsonDecoder.Buffered())
|
||||
if readErr != nil {
|
||||
glog.V(4).Infof("reading stream failed: %v", readErr)
|
||||
}
|
||||
js := string(data)
|
||||
start := strings.LastIndex(js[:syntax.Offset], "\n") + 1
|
||||
line := strings.Count(js[:start], "\n")
|
||||
return fmt.Errorf("json: line %d: %s", line, syntax.Error())
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
type Reader interface {
|
||||
Read() ([]byte, error)
|
||||
}
|
||||
|
||||
type YAMLReader struct {
|
||||
reader Reader
|
||||
}
|
||||
|
||||
func NewYAMLReader(r *bufio.Reader) *YAMLReader {
|
||||
return &YAMLReader{
|
||||
reader: &LineReader{reader: r},
|
||||
}
|
||||
}
|
||||
|
||||
// Read returns a full YAML document.
|
||||
func (r *YAMLReader) Read() ([]byte, error) {
|
||||
var buffer bytes.Buffer
|
||||
for {
|
||||
line, err := r.reader.Read()
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if string(line) == separator || err == io.EOF {
|
||||
if buffer.Len() != 0 {
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
if err == io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
buffer.Write(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type LineReader struct {
|
||||
reader *bufio.Reader
|
||||
}
|
||||
|
||||
// Read returns a single line (with '\n' ended) from the underlying reader.
|
||||
// An error is returned iff there is an error with the underlying reader.
|
||||
func (r *LineReader) Read() ([]byte, error) {
|
||||
var (
|
||||
isPrefix bool = true
|
||||
err error = nil
|
||||
line []byte
|
||||
buffer bytes.Buffer
|
||||
)
|
||||
|
||||
for isPrefix && err == nil {
|
||||
line, isPrefix, err = r.reader.ReadLine()
|
||||
buffer.Write(line)
|
||||
}
|
||||
buffer.WriteByte('\n')
|
||||
return buffer.Bytes(), err
|
||||
}
|
||||
|
||||
// GuessJSONStream scans the provided reader up to size, looking
|
||||
// for an open brace indicating this is JSON. It will return the
|
||||
// bufio.Reader it creates for the consumer.
|
||||
func GuessJSONStream(r io.Reader, size int) (io.Reader, bool) {
|
||||
buffer := bufio.NewReaderSize(r, size)
|
||||
b, _ := buffer.Peek(size)
|
||||
return buffer, hasJSONPrefix(b)
|
||||
}
|
||||
|
||||
var jsonPrefix = []byte("{")
|
||||
|
||||
// hasJSONPrefix returns true if the provided buffer appears to start with
|
||||
// a JSON open brace.
|
||||
func hasJSONPrefix(buf []byte) bool {
|
||||
return hasPrefix(buf, jsonPrefix)
|
||||
}
|
||||
|
||||
// Return true if the first non-whitespace bytes in buf is
|
||||
// prefix.
|
||||
func hasPrefix(buf []byte, prefix []byte) bool {
|
||||
trim := bytes.TrimLeftFunc(buf, unicode.IsSpace)
|
||||
return bytes.HasPrefix(trim, prefix)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue