1
0
Fork 0

Bump kubernetes/client-go

This commit is contained in:
Kim Min 2018-02-14 16:56:04 +08:00 committed by Traefiker Bot
parent 029fa83690
commit 83a92596c3
901 changed files with 169303 additions and 306433 deletions

View file

@ -23,7 +23,7 @@ import (
"sync"
"time"
utilnet "k8s.io/client-go/pkg/util/net"
utilnet "k8s.io/apimachinery/pkg/util/net"
)
// TlsTransportCache caches TLS http.RoundTrippers different configurations. The
@ -63,16 +63,20 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
return http.DefaultTransport, nil
}
dial := config.Dial
if dial == nil {
dial = (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial
}
// Cache a single transport for these options
c.transports[key] = utilnet.SetTransportDefaults(&http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: tlsConfig,
MaxIdleConnsPerHost: idleConnsPerHost,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
Dial: dial,
})
return c.transports[key], nil
}
@ -84,5 +88,5 @@ func tlsConfigKey(c *Config) (string, error) {
return "", err
}
// Only include the things that actually affect the tls.Config
return fmt.Sprintf("%v/%x/%x/%x", c.TLS.Insecure, c.TLS.CAData, c.TLS.CertData, c.TLS.KeyData), nil
return fmt.Sprintf("%v/%x/%x/%x/%v", c.TLS.Insecure, c.TLS.CAData, c.TLS.CertData, c.TLS.KeyData, c.TLS.ServerName), nil
}

View file

@ -16,7 +16,10 @@ limitations under the License.
package transport
import "net/http"
import (
"net"
"net/http"
)
// Config holds various options for establishing a transport.
type Config struct {
@ -34,8 +37,12 @@ type Config struct {
// Bearer token for authentication
BearerToken string
// Impersonate is the username that this Config will impersonate
Impersonate string
// CacheDir is the directory where we'll store HTTP cached responses.
// If set to empty string, no caching mechanism will be used.
CacheDir string
// Impersonate is the config that this Config will impersonate using
Impersonate ImpersonationConfig
// Transport may be used for custom HTTP behavior. This attribute may
// not be specified with the TLS client certificate options. Use
@ -48,6 +55,19 @@ type Config struct {
// config may layer other RoundTrippers on top of the returned
// RoundTripper.
WrapTransport func(rt http.RoundTripper) http.RoundTripper
// Dial specifies the dial function for creating unencrypted TCP connections.
Dial func(network, addr string) (net.Conn, error)
}
// ImpersonationConfig has all the available impersonation options
type ImpersonationConfig struct {
// UserName matches user.Info.GetName()
UserName string
// Groups matches user.Info.GetGroups()
Groups []string
// Extra matches user.Info.GetExtra()
Extra map[string][]string
}
// HasCA returns whether the configuration has a certificate authority or not.
@ -76,7 +96,8 @@ type TLSConfig struct {
CertFile string // Path of the PEM-encoded client certificate.
KeyFile string // Path of the PEM-encoded client key.
Insecure bool // Server should be accessed without verifying the certificate. For testing only.
Insecure bool // Server should be accessed without verifying the certificate. For testing only.
ServerName string // Override for the server name passed to the server for SNI and used to verify certificates.
CAData []byte // Bytes of the PEM-encoded server trusted root certificates. Supercedes CAFile.
CertData []byte // Bytes of the PEM-encoded client certificate. Supercedes CertFile.

View file

@ -19,9 +19,16 @@ package transport
import (
"fmt"
"net/http"
"path/filepath"
"strings"
"time"
"github.com/golang/glog"
"github.com/gregjones/httpcache"
"github.com/gregjones/httpcache/diskcache"
"github.com/peterbourgon/diskv"
utilnet "k8s.io/apimachinery/pkg/util/net"
)
// HTTPWrappersForConfig wraps a round tripper with any relevant layered
@ -48,9 +55,14 @@ func HTTPWrappersForConfig(config *Config, rt http.RoundTripper) (http.RoundTrip
if len(config.UserAgent) > 0 {
rt = NewUserAgentRoundTripper(config.UserAgent, rt)
}
if len(config.Impersonate) > 0 {
if len(config.Impersonate.UserName) > 0 ||
len(config.Impersonate.Groups) > 0 ||
len(config.Impersonate.Extra) > 0 {
rt = NewImpersonatingRoundTripper(config.Impersonate, rt)
}
if len(config.CacheDir) > 0 {
rt = NewCacheRoundTripper(config.CacheDir, rt)
}
return rt, nil
}
@ -74,6 +86,95 @@ type requestCanceler interface {
CancelRequest(*http.Request)
}
type cacheRoundTripper struct {
rt *httpcache.Transport
}
// NewCacheRoundTripper creates a roundtripper that reads the ETag on
// response headers and send the If-None-Match header on subsequent
// corresponding requests.
func NewCacheRoundTripper(cacheDir string, rt http.RoundTripper) http.RoundTripper {
d := diskv.New(diskv.Options{
BasePath: cacheDir,
TempDir: filepath.Join(cacheDir, ".diskv-temp"),
})
t := httpcache.NewTransport(diskcache.NewWithDiskv(d))
t.Transport = rt
return &cacheRoundTripper{rt: t}
}
func (rt *cacheRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
return rt.rt.RoundTrip(req)
}
func (rt *cacheRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt.Transport }
type authProxyRoundTripper struct {
username string
groups []string
extra map[string][]string
rt http.RoundTripper
}
// NewAuthProxyRoundTripper provides a roundtripper which will add auth proxy fields to requests for
// authentication terminating proxy cases
// assuming you pull the user from the context:
// username is the user.Info.GetName() of the user
// groups is the user.Info.GetGroups() of the user
// extra is the user.Info.GetExtra() of the user
// extra can contain any additional information that the authenticator
// thought was interesting, for example authorization scopes.
// In order to faithfully round-trip through an impersonation flow, these keys
// MUST be lowercase.
func NewAuthProxyRoundTripper(username string, groups []string, extra map[string][]string, rt http.RoundTripper) http.RoundTripper {
return &authProxyRoundTripper{
username: username,
groups: groups,
extra: extra,
rt: rt,
}
}
func (rt *authProxyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
req = utilnet.CloneRequest(req)
SetAuthProxyHeaders(req, rt.username, rt.groups, rt.extra)
return rt.rt.RoundTrip(req)
}
// SetAuthProxyHeaders stomps the auth proxy header fields. It mutates its argument.
func SetAuthProxyHeaders(req *http.Request, username string, groups []string, extra map[string][]string) {
req.Header.Del("X-Remote-User")
req.Header.Del("X-Remote-Group")
for key := range req.Header {
if strings.HasPrefix(strings.ToLower(key), strings.ToLower("X-Remote-Extra-")) {
req.Header.Del(key)
}
}
req.Header.Set("X-Remote-User", username)
for _, group := range groups {
req.Header.Add("X-Remote-Group", group)
}
for key, values := range extra {
for _, value := range values {
req.Header.Add("X-Remote-Extra-"+key, value)
}
}
}
func (rt *authProxyRoundTripper) CancelRequest(req *http.Request) {
if canceler, ok := rt.rt.(requestCanceler); ok {
canceler.CancelRequest(req)
} else {
glog.Errorf("CancelRequest not implemented")
}
}
func (rt *authProxyRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
type userAgentRoundTripper struct {
agent string
rt http.RoundTripper
@ -87,7 +188,7 @@ func (rt *userAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, e
if len(req.Header.Get("User-Agent")) != 0 {
return rt.rt.RoundTrip(req)
}
req = cloneRequest(req)
req = utilnet.CloneRequest(req)
req.Header.Set("User-Agent", rt.agent)
return rt.rt.RoundTrip(req)
}
@ -118,7 +219,7 @@ func (rt *basicAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, e
if len(req.Header.Get("Authorization")) != 0 {
return rt.rt.RoundTrip(req)
}
req = cloneRequest(req)
req = utilnet.CloneRequest(req)
req.SetBasicAuth(rt.username, rt.password)
return rt.rt.RoundTrip(req)
}
@ -133,22 +234,53 @@ func (rt *basicAuthRoundTripper) CancelRequest(req *http.Request) {
func (rt *basicAuthRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
// These correspond to the headers used in pkg/apis/authentication. We don't want the package dependency,
// but you must not change the values.
const (
// ImpersonateUserHeader is used to impersonate a particular user during an API server request
ImpersonateUserHeader = "Impersonate-User"
// ImpersonateGroupHeader is used to impersonate a particular group during an API server request.
// It can be repeated multiplied times for multiple groups.
ImpersonateGroupHeader = "Impersonate-Group"
// ImpersonateUserExtraHeaderPrefix is a prefix for a header used to impersonate an entry in the
// extra map[string][]string for user.Info. The key for the `extra` map is suffix.
// The same key can be repeated multiple times to have multiple elements in the slice under a single key.
// For instance:
// Impersonate-Extra-Foo: one
// Impersonate-Extra-Foo: two
// results in extra["Foo"] = []string{"one", "two"}
ImpersonateUserExtraHeaderPrefix = "Impersonate-Extra-"
)
type impersonatingRoundTripper struct {
impersonate string
impersonate ImpersonationConfig
delegate http.RoundTripper
}
// NewImpersonatingRoundTripper will add an Act-As header to a request unless it has already been set.
func NewImpersonatingRoundTripper(impersonate string, delegate http.RoundTripper) http.RoundTripper {
func NewImpersonatingRoundTripper(impersonate ImpersonationConfig, delegate http.RoundTripper) http.RoundTripper {
return &impersonatingRoundTripper{impersonate, delegate}
}
func (rt *impersonatingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
if len(req.Header.Get("Impersonate-User")) != 0 {
// use the user header as marker for the rest.
if len(req.Header.Get(ImpersonateUserHeader)) != 0 {
return rt.delegate.RoundTrip(req)
}
req = cloneRequest(req)
req.Header.Set("Impersonate-User", rt.impersonate)
req = utilnet.CloneRequest(req)
req.Header.Set(ImpersonateUserHeader, rt.impersonate.UserName)
for _, group := range rt.impersonate.Groups {
req.Header.Add(ImpersonateGroupHeader, group)
}
for k, vv := range rt.impersonate.Extra {
for _, v := range vv {
req.Header.Add(ImpersonateUserExtraHeaderPrefix+k, v)
}
}
return rt.delegate.RoundTrip(req)
}
@ -178,7 +310,7 @@ func (rt *bearerAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response,
return rt.rt.RoundTrip(req)
}
req = cloneRequest(req)
req = utilnet.CloneRequest(req)
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", rt.bearer))
return rt.rt.RoundTrip(req)
}
@ -193,20 +325,6 @@ func (rt *bearerAuthRoundTripper) CancelRequest(req *http.Request) {
func (rt *bearerAuthRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
// cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map.
func cloneRequest(r *http.Request) *http.Request {
// shallow copy of the struct
r2 := new(http.Request)
*r2 = *r
// deep copy of the Header
r2.Header = make(http.Header)
for k, s := range r.Header {
r2.Header[k] = s
}
return r2
}
// requestInfo keeps track of information about a request/response combination
type requestInfo struct {
RequestHeaders http.Header

View file

@ -68,6 +68,7 @@ func TLSConfigFor(c *Config) (*tls.Config, error) {
// Can't use TLSv1.1 because of RC4 cipher usage
MinVersion: tls.VersionTLS12,
InsecureSkipVerify: c.TLS.Insecure,
ServerName: c.TLS.ServerName,
}
if c.HasCA() {