-
Notifications
You must be signed in to change notification settings - Fork 0
/
client_config.go
131 lines (110 loc) · 4.05 KB
/
client_config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package client
import (
"io/ioutil"
"net"
"net/http"
"time"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
configv1 "github.com/openshift/api/config/v1"
)
// GetKubeConfigOrInClusterConfig loads in-cluster config if kubeConfigFile is empty or the file if not,
// then applies overrides.
func GetKubeConfigOrInClusterConfig(kubeConfigFile string, overrides *ClientConnectionOverrides) (*rest.Config, error) {
if len(kubeConfigFile) > 0 {
return GetClientConfig(kubeConfigFile, overrides)
}
clientConfig, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
applyClientConnectionOverrides(overrides, clientConfig)
t := ClientTransportOverrides{WrapTransport: clientConfig.WrapTransport}
if overrides != nil {
t.MaxIdleConnsPerHost = overrides.MaxIdleConnsPerHost
}
clientConfig.WrapTransport = t.DefaultClientTransport
return clientConfig, nil
}
// GetClientConfig returns the rest.Config for a kubeconfig file
func GetClientConfig(kubeConfigFile string, overrides *ClientConnectionOverrides) (*rest.Config, error) {
kubeConfigBytes, err := ioutil.ReadFile(kubeConfigFile)
if err != nil {
return nil, err
}
kubeConfig, err := clientcmd.NewClientConfigFromBytes(kubeConfigBytes)
if err != nil {
return nil, err
}
clientConfig, err := kubeConfig.ClientConfig()
if err != nil {
return nil, err
}
applyClientConnectionOverrides(overrides, clientConfig)
t := ClientTransportOverrides{WrapTransport: clientConfig.WrapTransport}
if overrides != nil {
t.MaxIdleConnsPerHost = overrides.MaxIdleConnsPerHost
}
clientConfig.WrapTransport = t.DefaultClientTransport
return clientConfig, nil
}
// applyClientConnectionOverrides updates a kubeConfig with the overrides from the config.
func applyClientConnectionOverrides(overrides *ClientConnectionOverrides, kubeConfig *rest.Config) {
if overrides == nil {
return
}
if overrides.QPS > 0 {
kubeConfig.QPS = overrides.QPS
}
if overrides.Burst > 0 {
kubeConfig.Burst = int(overrides.Burst)
}
if len(overrides.AcceptContentTypes) > 0 {
kubeConfig.ContentConfig.AcceptContentTypes = overrides.AcceptContentTypes
}
if len(overrides.ContentType) > 0 {
kubeConfig.ContentConfig.ContentType = overrides.ContentType
}
// TODO both of these default values look wrong
// if we have no preferences at this point, claim that we accept both proto and json. We will get proto if the server supports it.
// this is a slightly niggly thing. If the server has proto and our client does not (possible, but not super likely) then this fails.
if len(kubeConfig.ContentConfig.AcceptContentTypes) == 0 {
kubeConfig.ContentConfig.AcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json"
}
if len(kubeConfig.ContentConfig.ContentType) == 0 {
kubeConfig.ContentConfig.ContentType = "application/vnd.kubernetes.protobuf"
}
}
type ClientTransportOverrides struct {
WrapTransport func(rt http.RoundTripper) http.RoundTripper
MaxIdleConnsPerHost int
}
// defaultClientTransport sets defaults for a client Transport that are suitable for use by infrastructure components.
func (c ClientTransportOverrides) DefaultClientTransport(rt http.RoundTripper) http.RoundTripper {
transport, ok := rt.(*http.Transport)
if !ok {
return rt
}
transport.DialContext = (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext
// Hold open more internal idle connections
transport.MaxIdleConnsPerHost = 100
if c.MaxIdleConnsPerHost > 0 {
transport.MaxIdleConnsPerHost = c.MaxIdleConnsPerHost
}
if c.WrapTransport == nil {
return transport
}
return c.WrapTransport(transport)
}
// ClientConnectionOverrides allows overriding values for rest.Config not held in a kubeconfig. Most commonly used
// for QPS. Empty values are not used.
type ClientConnectionOverrides struct {
configv1.ClientConnectionOverrides
// MaxIdleConnsPerHost, if non-zero, controls the maximum idle (keep-alive) connections to keep per-host:port.
// If zero, DefaultMaxIdleConnsPerHost is used.
// TODO roll this into the connection overrides in api
MaxIdleConnsPerHost int
}