-
Notifications
You must be signed in to change notification settings - Fork 0
/
dial.go
86 lines (74 loc) · 2.61 KB
/
dial.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
package aviation
import (
"context"
"crypto/tls"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// DialOptions describes the options for creating a client connection to a RPC
// service via gRPC.
type DialOptions struct {
// Address is the RPC address to connect to.
Address string
// Retries specifies the number of times the client connection retries
// an operation before failing.
Retries int
// TLSConf is the config for TLS authentication. If TLSConf is
// specified, CAFile, CrtFile, and KeyFile are ignored. If neither
// TLSFile nor the certificate files are specified, the connection is
// created without TLS. (Optional)
TLSConf *tls.Config
// CAFile is the name of the file with the CA certificate for TLS. If
// specified, CrtFile and KeyFile must also be specified. (Optional)
CAFile string
// CrtFile is the name of the file with the user certificate for TLS.
// If specified, CAFile and KeyFile must also be specified. (Optional)
CrtFile string
// KeyFile is the name of the file with the key certificate for TLS. If
// specified, CAFile and CrtFile must also be specified. (Optional)
KeyFile string
}
func (opts *DialOptions) validate() error {
if opts.Address == "" {
return errors.New("must provide rpc address")
}
if opts.TLSConf == nil && (opts.CAFile == "") != (opts.CrtFile == "") != (opts.KeyFile == "") {
return errors.New("must provide all or none of the required certificate filenames")
}
return nil
}
func (opts *DialOptions) getOpts() ([]grpc.DialOption, error) {
if err := opts.validate(); err != nil {
return nil, err
}
dialOpts := []grpc.DialOption{}
if opts.Retries > 0 {
dialOpts = append(
dialOpts,
grpc.WithUnaryInterceptor(MakeRetryUnaryClientInterceptor(opts.Retries)),
grpc.WithStreamInterceptor(MakeRetryStreamClientInterceptor(opts.Retries)),
)
}
tlsConf := opts.TLSConf
if tlsConf == nil && opts.CAFile != "" {
var err error
tlsConf, err = GetClientTLSConfigFromFiles(opts.CAFile, opts.CrtFile, opts.KeyFile)
if err != nil {
return nil, errors.Wrap(err, "problem getting client TLS config")
}
}
if tlsConf != nil {
dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConf)))
}
return dialOpts, nil
}
// Dial creates a client connection to a RPC service via gRPC.
func Dial(ctx context.Context, opts DialOptions) (*grpc.ClientConn, error) {
dialOpts, err := opts.getOpts()
if err != nil {
return nil, errors.Wrap(err, "problem getting gRPC dial options")
}
conn, err := grpc.DialContext(ctx, opts.Address, dialOpts...)
return conn, errors.Wrap(err, "problem dialing rpc")
}