-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Expand file tree
/
Copy pathetcd.go
More file actions
135 lines (121 loc) · 4.06 KB
/
etcd.go
File metadata and controls
135 lines (121 loc) · 4.06 KB
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
132
133
134
135
package etcd
import (
"fmt"
"net"
"net/http"
"time"
etcdclient "github.com/coreos/etcd/client"
clientv3 "github.com/coreos/etcd/clientv3"
"golang.org/x/net/context"
knet "k8s.io/apimachinery/pkg/util/net"
etcdutil "k8s.io/apiserver/pkg/storage/etcd/util"
restclient "k8s.io/client-go/rest"
configapi "github.com/openshift/origin/pkg/cmd/server/api"
)
// GetAndTestEtcdClient creates an etcd client based on the provided config. It will attempt to
// connect to the etcd server and block until the server responds at least once, or return an
// error if the server never responded.
func GetAndTestEtcdClient(etcdClientInfo configapi.EtcdConnectionInfo) (etcdclient.Client, error) {
etcdClient, err := MakeEtcdClient(etcdClientInfo)
if err != nil {
return nil, err
}
if err := TestEtcdClient(etcdClient); err != nil {
return nil, err
}
return etcdClient, nil
}
// MakeEtcdClient creates an etcd client based on the provided config.
func MakeEtcdClient(etcdClientInfo configapi.EtcdConnectionInfo) (etcdclient.Client, error) {
tlsConfig, err := restclient.TLSConfigFor(&restclient.Config{
TLSClientConfig: restclient.TLSClientConfig{
CertFile: etcdClientInfo.ClientCert.CertFile,
KeyFile: etcdClientInfo.ClientCert.KeyFile,
CAFile: etcdClientInfo.CA,
},
})
if err != nil {
return nil, err
}
transport := knet.SetTransportDefaults(&http.Transport{
TLSClientConfig: tlsConfig,
Dial: (&net.Dialer{
// default from http.DefaultTransport
Timeout: 30 * time.Second,
// Lower the keep alive for connections.
KeepAlive: 1 * time.Second,
}).Dial,
// Because watches are very bursty, defends against long delays in watch reconnections.
MaxIdleConnsPerHost: 500,
})
cfg := etcdclient.Config{
Endpoints: etcdClientInfo.URLs,
// TODO: Determine if transport needs optimization
Transport: transport,
}
return etcdclient.New(cfg)
}
// TestEtcdClient verifies a client is functional. It will attempt to
// connect to the etcd server and block until the server responds at least once, or return an
// error if the server never responded.
func TestEtcdClient(etcdClient etcdclient.Client) error {
for i := 0; ; i++ {
_, err := etcdclient.NewKeysAPI(etcdClient).Get(context.Background(), "/", nil)
if err == nil || etcdutil.IsEtcdNotFound(err) {
break
}
if i > 100 {
return fmt.Errorf("could not reach etcd: %v", err)
}
time.Sleep(50 * time.Millisecond)
}
return nil
}
// GetAndTestEtcdClientV3 creates an etcd client based on the provided config. It will attempt to
// connect to the etcd server and block until the server responds at least once, or return an
// error if the server never responded.
func GetAndTestEtcdClientV3(etcdClientInfo configapi.EtcdConnectionInfo) (*clientv3.Client, error) {
etcdClient, err := MakeEtcdClientV3(etcdClientInfo)
if err != nil {
return nil, err
}
if err := TestEtcdClientV3(etcdClient); err != nil {
return nil, err
}
return etcdClient, nil
}
// MakeEtcdClient creates an etcd client based on the provided config.
func MakeEtcdClientV3(etcdClientInfo configapi.EtcdConnectionInfo) (*clientv3.Client, error) {
tlsConfig, err := restclient.TLSConfigFor(&restclient.Config{
TLSClientConfig: restclient.TLSClientConfig{
CertFile: etcdClientInfo.ClientCert.CertFile,
KeyFile: etcdClientInfo.ClientCert.KeyFile,
CAFile: etcdClientInfo.CA,
},
})
if err != nil {
return nil, err
}
cfg := clientv3.Config{
Endpoints: etcdClientInfo.URLs,
DialTimeout: 30 * time.Second,
TLS: tlsConfig,
}
return clientv3.New(cfg)
}
// TestEtcdClient verifies a client is functional. It will attempt to
// connect to the etcd server and block until the server responds at least once, or return an
// error if the server never responded.
func TestEtcdClientV3(etcdClient *clientv3.Client) error {
for i := 0; ; i++ {
_, err := clientv3.NewKV(etcdClient).Get(context.Background(), "/", clientv3.WithLimit(1))
if err == nil || etcdutil.IsEtcdNotFound(err) {
break
}
if i > 100 {
return fmt.Errorf("could not reach etcd: %v", err)
}
time.Sleep(50 * time.Millisecond)
}
return nil
}