Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / k8s.io / client-go / transport / cache.go
1 /*
2 Copyright 2015 The Kubernetes Authors.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 package transport
18
19 import (
20         "fmt"
21         "net"
22         "net/http"
23         "sync"
24         "time"
25
26         utilnet "k8s.io/apimachinery/pkg/util/net"
27 )
28
29 // TlsTransportCache caches TLS http.RoundTrippers different configurations. The
30 // same RoundTripper will be returned for configs with identical TLS options If
31 // the config has no custom TLS options, http.DefaultTransport is returned.
32 type tlsTransportCache struct {
33         mu         sync.Mutex
34         transports map[tlsCacheKey]*http.Transport
35 }
36
37 const idleConnsPerHost = 25
38
39 var tlsCache = &tlsTransportCache{transports: make(map[tlsCacheKey]*http.Transport)}
40
41 type tlsCacheKey struct {
42         insecure   bool
43         caData     string
44         certData   string
45         keyData    string
46         getCert    string
47         serverName string
48         dial       string
49 }
50
51 func (t tlsCacheKey) String() string {
52         keyText := "<none>"
53         if len(t.keyData) > 0 {
54                 keyText = "<redacted>"
55         }
56         return fmt.Sprintf("insecure:%v, caData:%#v, certData:%#v, keyData:%s, getCert: %s, serverName:%s, dial:%s", t.insecure, t.caData, t.certData, keyText, t.getCert, t.serverName, t.dial)
57 }
58
59 func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
60         key, err := tlsConfigKey(config)
61         if err != nil {
62                 return nil, err
63         }
64
65         // Ensure we only create a single transport for the given TLS options
66         c.mu.Lock()
67         defer c.mu.Unlock()
68
69         // See if we already have a custom transport for this config
70         if t, ok := c.transports[key]; ok {
71                 return t, nil
72         }
73
74         // Get the TLS options for this client config
75         tlsConfig, err := TLSConfigFor(config)
76         if err != nil {
77                 return nil, err
78         }
79         // The options didn't require a custom TLS config
80         if tlsConfig == nil && config.Dial == nil {
81                 return http.DefaultTransport, nil
82         }
83
84         dial := config.Dial
85         if dial == nil {
86                 dial = (&net.Dialer{
87                         Timeout:   30 * time.Second,
88                         KeepAlive: 30 * time.Second,
89                 }).DialContext
90         }
91         // Cache a single transport for these options
92         c.transports[key] = utilnet.SetTransportDefaults(&http.Transport{
93                 Proxy:               http.ProxyFromEnvironment,
94                 TLSHandshakeTimeout: 10 * time.Second,
95                 TLSClientConfig:     tlsConfig,
96                 MaxIdleConnsPerHost: idleConnsPerHost,
97                 DialContext:         dial,
98         })
99         return c.transports[key], nil
100 }
101
102 // tlsConfigKey returns a unique key for tls.Config objects returned from TLSConfigFor
103 func tlsConfigKey(c *Config) (tlsCacheKey, error) {
104         // Make sure ca/key/cert content is loaded
105         if err := loadTLSFiles(c); err != nil {
106                 return tlsCacheKey{}, err
107         }
108         return tlsCacheKey{
109                 insecure:   c.TLS.Insecure,
110                 caData:     string(c.TLS.CAData),
111                 certData:   string(c.TLS.CertData),
112                 keyData:    string(c.TLS.KeyData),
113                 getCert:    fmt.Sprintf("%p", c.TLS.GetCert),
114                 serverName: c.TLS.ServerName,
115                 dial:       fmt.Sprintf("%p", c.Dial),
116         }, nil
117 }