Custom resource definition
Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
This commit is contained in:
parent
cfaf47c8a2
commit
4c060a78cc
1348 changed files with 92364 additions and 55766 deletions
42
vendor/k8s.io/client-go/util/cert/cert.go
generated
vendored
42
vendor/k8s.io/client-go/util/cert/cert.go
generated
vendored
|
@ -38,7 +38,7 @@ const (
|
|||
duration365d = time.Hour * 24 * 365
|
||||
)
|
||||
|
||||
// Config containes the basic fields required for creating a certificate
|
||||
// Config contains the basic fields required for creating a certificate
|
||||
type Config struct {
|
||||
CommonName string
|
||||
Organization []string
|
||||
|
@ -138,23 +138,50 @@ func MakeEllipticPrivateKeyPEM() ([]byte, error) {
|
|||
// 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
|
||||
func GenerateSelfSignedCertKey(host string, alternateIPs []net.IP, alternateDNS []string) ([]byte, []byte, error) {
|
||||
caKey, err := rsa.GenerateKey(cryptorand.Reader, 2048)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
caTemplate := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("%s-ca@%d", host, time.Now().Unix()),
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(time.Hour * 24 * 365),
|
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
}
|
||||
|
||||
caDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &caTemplate, &caTemplate, &caKey.PublicKey, caKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
caCertificate, err := x509.ParseCertificate(caDERBytes)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
priv, err := rsa.GenerateKey(cryptorand.Reader, 2048)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
SerialNumber: big.NewInt(2),
|
||||
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,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
}
|
||||
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
|
@ -166,16 +193,19 @@ func GenerateSelfSignedCertKey(host string, alternateIPs []net.IP, alternateDNS
|
|||
template.IPAddresses = append(template.IPAddresses, alternateIPs...)
|
||||
template.DNSNames = append(template.DNSNames, alternateDNS...)
|
||||
|
||||
derBytes, err := x509.CreateCertificate(cryptorand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
derBytes, err := x509.CreateCertificate(cryptorand.Reader, &template, caCertificate, &priv.PublicKey, caKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Generate cert
|
||||
// Generate cert, followed by ca
|
||||
certBuffer := bytes.Buffer{}
|
||||
if err := pem.Encode(&certBuffer, &pem.Block{Type: CertificateBlockType, Bytes: derBytes}); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := pem.Encode(&certBuffer, &pem.Block{Type: CertificateBlockType, Bytes: caDERBytes}); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Generate key
|
||||
keyBuffer := bytes.Buffer{}
|
||||
|
|
37
vendor/k8s.io/client-go/util/cert/io.go
generated
vendored
37
vendor/k8s.io/client-go/util/cert/io.go
generated
vendored
|
@ -17,7 +17,11 @@ limitations under the License.
|
|||
package cert
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -84,7 +88,8 @@ func WriteKey(keyPath string, data []byte) error {
|
|||
// can't find one, it will generate a new key and store it there.
|
||||
func LoadOrGenerateKeyFile(keyPath string) (data []byte, wasGenerated bool, err error) {
|
||||
loadedData, err := ioutil.ReadFile(keyPath)
|
||||
if err == nil {
|
||||
// Call verifyKeyData to ensure the file wasn't empty/corrupt.
|
||||
if err == nil && verifyKeyData(loadedData) {
|
||||
return loadedData, false, err
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
|
@ -101,6 +106,27 @@ func LoadOrGenerateKeyFile(keyPath string) (data []byte, wasGenerated bool, err
|
|||
return generatedData, true, nil
|
||||
}
|
||||
|
||||
// MarshalPrivateKeyToPEM converts a known private key type of RSA or ECDSA to
|
||||
// a PEM encoded block or returns an error.
|
||||
func MarshalPrivateKeyToPEM(privateKey crypto.PrivateKey) ([]byte, error) {
|
||||
switch t := privateKey.(type) {
|
||||
case *ecdsa.PrivateKey:
|
||||
derBytes, err := x509.MarshalECPrivateKey(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
privateKeyPemBlock := &pem.Block{
|
||||
Type: ECPrivateKeyBlockType,
|
||||
Bytes: derBytes,
|
||||
}
|
||||
return pem.EncodeToMemory(privateKeyPemBlock), nil
|
||||
case *rsa.PrivateKey:
|
||||
return EncodePrivateKeyPEM(t), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("private key is not a recognized type: %T", privateKey)
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
@ -156,3 +182,12 @@ func PublicKeysFromFile(file string) ([]interface{}, error) {
|
|||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// verifyKeyData returns true if the provided data appears to be a valid private key.
|
||||
func verifyKeyData(data []byte) bool {
|
||||
if len(data) == 0 {
|
||||
return false
|
||||
}
|
||||
_, err := ParsePrivateKeyPEM(data)
|
||||
return err == nil
|
||||
}
|
||||
|
|
105
vendor/k8s.io/client-go/util/connrotation/connrotation.go
generated
vendored
Normal file
105
vendor/k8s.io/client-go/util/connrotation/connrotation.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package connrotation implements a connection dialer that tracks and can close
|
||||
// all created connections.
|
||||
//
|
||||
// This is used for credential rotation of long-lived connections, when there's
|
||||
// no way to re-authenticate on a live connection.
|
||||
package connrotation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// DialFunc is a shorthand for signature of net.DialContext.
|
||||
type DialFunc func(ctx context.Context, network, address string) (net.Conn, error)
|
||||
|
||||
// Dialer opens connections through Dial and tracks them.
|
||||
type Dialer struct {
|
||||
dial DialFunc
|
||||
|
||||
mu sync.Mutex
|
||||
conns map[*closableConn]struct{}
|
||||
}
|
||||
|
||||
// NewDialer creates a new Dialer instance.
|
||||
//
|
||||
// If dial is not nil, it will be used to create new underlying connections.
|
||||
// Otherwise net.DialContext is used.
|
||||
func NewDialer(dial DialFunc) *Dialer {
|
||||
return &Dialer{
|
||||
dial: dial,
|
||||
conns: make(map[*closableConn]struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// CloseAll forcibly closes all tracked connections.
|
||||
//
|
||||
// Note: new connections may get created before CloseAll returns.
|
||||
func (d *Dialer) CloseAll() {
|
||||
d.mu.Lock()
|
||||
conns := d.conns
|
||||
d.conns = make(map[*closableConn]struct{})
|
||||
d.mu.Unlock()
|
||||
|
||||
for conn := range conns {
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Dial creates a new tracked connection.
|
||||
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
||||
return d.DialContext(context.Background(), network, address)
|
||||
}
|
||||
|
||||
// DialContext creates a new tracked connection.
|
||||
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
conn, err := d.dial(ctx, network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
closable := &closableConn{Conn: conn}
|
||||
|
||||
// Start tracking the connection
|
||||
d.mu.Lock()
|
||||
d.conns[closable] = struct{}{}
|
||||
d.mu.Unlock()
|
||||
|
||||
// When the connection is closed, remove it from the map. This will
|
||||
// be no-op if the connection isn't in the map, e.g. if CloseAll()
|
||||
// is called.
|
||||
closable.onClose = func() {
|
||||
d.mu.Lock()
|
||||
delete(d.conns, closable)
|
||||
d.mu.Unlock()
|
||||
}
|
||||
|
||||
return closable, nil
|
||||
}
|
||||
|
||||
type closableConn struct {
|
||||
onClose func()
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (c *closableConn) Close() error {
|
||||
go c.onClose()
|
||||
return c.Conn.Close()
|
||||
}
|
55
vendor/k8s.io/client-go/util/flowcontrol/throttle.go
generated
vendored
55
vendor/k8s.io/client-go/util/flowcontrol/throttle.go
generated
vendored
|
@ -18,8 +18,9 @@ package flowcontrol
|
|||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/juju/ratelimit"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
type RateLimiter interface {
|
||||
|
@ -30,17 +31,13 @@ type RateLimiter interface {
|
|||
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
|
||||
limiter *rate.Limiter
|
||||
clock Clock
|
||||
qps float32
|
||||
}
|
||||
|
||||
|
@ -50,42 +47,48 @@ type tokenBucketRateLimiter struct {
|
|||
// 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 newTokenBucketRateLimiter(limiter, qps)
|
||||
limiter := rate.NewLimiter(rate.Limit(qps), burst)
|
||||
return newTokenBucketRateLimiter(limiter, realClock{}, qps)
|
||||
}
|
||||
|
||||
// An injectable, mockable clock interface.
|
||||
type Clock interface {
|
||||
ratelimit.Clock
|
||||
Now() time.Time
|
||||
Sleep(time.Duration)
|
||||
}
|
||||
|
||||
type realClock struct{}
|
||||
|
||||
func (realClock) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
func (realClock) Sleep(d time.Duration) {
|
||||
time.Sleep(d)
|
||||
}
|
||||
|
||||
// NewTokenBucketRateLimiterWithClock is identical to NewTokenBucketRateLimiter
|
||||
// but allows an injectable clock, for testing.
|
||||
func NewTokenBucketRateLimiterWithClock(qps float32, burst int, clock Clock) RateLimiter {
|
||||
limiter := ratelimit.NewBucketWithRateAndClock(float64(qps), int64(burst), clock)
|
||||
return newTokenBucketRateLimiter(limiter, qps)
|
||||
func NewTokenBucketRateLimiterWithClock(qps float32, burst int, c Clock) RateLimiter {
|
||||
limiter := rate.NewLimiter(rate.Limit(qps), burst)
|
||||
return newTokenBucketRateLimiter(limiter, c, qps)
|
||||
}
|
||||
|
||||
func newTokenBucketRateLimiter(limiter *ratelimit.Bucket, qps float32) RateLimiter {
|
||||
func newTokenBucketRateLimiter(limiter *rate.Limiter, c Clock, qps float32) RateLimiter {
|
||||
return &tokenBucketRateLimiter{
|
||||
limiter: limiter,
|
||||
clock: c,
|
||||
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)
|
||||
return t.limiter.AllowN(t.clock.Now(), 1)
|
||||
}
|
||||
|
||||
// Accept will block until a token becomes available
|
||||
func (t *tokenBucketRateLimiter) Accept() {
|
||||
t.limiter.Wait(1)
|
||||
now := t.clock.Now()
|
||||
t.clock.Sleep(t.limiter.ReserveN(now, 1).DelayFrom(now))
|
||||
}
|
||||
|
||||
func (t *tokenBucketRateLimiter) Stop() {
|
||||
|
@ -105,10 +108,6 @@ func (t *fakeAlwaysRateLimiter) TryAccept() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) Saturation() float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) Stop() {}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) Accept() {}
|
||||
|
@ -131,10 +130,6 @@ func (t *fakeNeverRateLimiter) TryAccept() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) Saturation() float64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) Stop() {
|
||||
t.wg.Done()
|
||||
}
|
||||
|
|
79
vendor/k8s.io/client-go/util/retry/util.go
generated
vendored
Normal file
79
vendor/k8s.io/client-go/util/retry/util.go
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
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 retry
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
// DefaultRetry is the recommended retry for a conflict where multiple clients
|
||||
// are making changes to the same resource.
|
||||
var DefaultRetry = wait.Backoff{
|
||||
Steps: 5,
|
||||
Duration: 10 * time.Millisecond,
|
||||
Factor: 1.0,
|
||||
Jitter: 0.1,
|
||||
}
|
||||
|
||||
// DefaultBackoff is the recommended backoff for a conflict where a client
|
||||
// may be attempting to make an unrelated modification to a resource under
|
||||
// active management by one or more controllers.
|
||||
var DefaultBackoff = wait.Backoff{
|
||||
Steps: 4,
|
||||
Duration: 10 * time.Millisecond,
|
||||
Factor: 5.0,
|
||||
Jitter: 0.1,
|
||||
}
|
||||
|
||||
// RetryConflict executes the provided function repeatedly, retrying if the server returns a conflicting
|
||||
// write. Callers should preserve previous executions if they wish to retry changes. It performs an
|
||||
// exponential backoff.
|
||||
//
|
||||
// var pod *api.Pod
|
||||
// err := RetryOnConflict(DefaultBackoff, func() (err error) {
|
||||
// pod, err = c.Pods("mynamespace").UpdateStatus(podStatus)
|
||||
// return
|
||||
// })
|
||||
// if err != nil {
|
||||
// // may be conflict if max retries were hit
|
||||
// return err
|
||||
// }
|
||||
// ...
|
||||
//
|
||||
// TODO: Make Backoff an interface?
|
||||
func RetryOnConflict(backoff wait.Backoff, fn func() error) error {
|
||||
var lastConflictErr error
|
||||
err := wait.ExponentialBackoff(backoff, func() (bool, error) {
|
||||
err := fn()
|
||||
switch {
|
||||
case err == nil:
|
||||
return true, nil
|
||||
case errors.IsConflict(err):
|
||||
lastConflictErr = err
|
||||
return false, nil
|
||||
default:
|
||||
return false, err
|
||||
}
|
||||
})
|
||||
if err == wait.ErrWaitTimeout {
|
||||
err = lastConflictErr
|
||||
}
|
||||
return err
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue