aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/go-plugin/grpc_client.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/go-plugin/grpc_client.go')
-rw-r--r--vendor/github.com/hashicorp/go-plugin/grpc_client.go107
1 files changed, 107 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-plugin/grpc_client.go b/vendor/github.com/hashicorp/go-plugin/grpc_client.go
new file mode 100644
index 0000000..44294d0
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-plugin/grpc_client.go
@@ -0,0 +1,107 @@
1package plugin
2
3import (
4 "crypto/tls"
5 "fmt"
6 "net"
7 "time"
8
9 "golang.org/x/net/context"
10 "google.golang.org/grpc"
11 "google.golang.org/grpc/credentials"
12 "google.golang.org/grpc/health/grpc_health_v1"
13)
14
15func dialGRPCConn(tls *tls.Config, dialer func(string, time.Duration) (net.Conn, error)) (*grpc.ClientConn, error) {
16 // Build dialing options.
17 opts := make([]grpc.DialOption, 0, 5)
18
19 // We use a custom dialer so that we can connect over unix domain sockets
20 opts = append(opts, grpc.WithDialer(dialer))
21
22 // go-plugin expects to block the connection
23 opts = append(opts, grpc.WithBlock())
24
25 // Fail right away
26 opts = append(opts, grpc.FailOnNonTempDialError(true))
27
28 // If we have no TLS configuration set, we need to explicitly tell grpc
29 // that we're connecting with an insecure connection.
30 if tls == nil {
31 opts = append(opts, grpc.WithInsecure())
32 } else {
33 opts = append(opts, grpc.WithTransportCredentials(
34 credentials.NewTLS(tls)))
35 }
36
37 // Connect. Note the first parameter is unused because we use a custom
38 // dialer that has the state to see the address.
39 conn, err := grpc.Dial("unused", opts...)
40 if err != nil {
41 return nil, err
42 }
43
44 return conn, nil
45}
46
47// newGRPCClient creates a new GRPCClient. The Client argument is expected
48// to be successfully started already with a lock held.
49func newGRPCClient(doneCtx context.Context, c *Client) (*GRPCClient, error) {
50 conn, err := dialGRPCConn(c.config.TLSConfig, c.dialer)
51 if err != nil {
52 return nil, err
53 }
54
55 // Start the broker.
56 brokerGRPCClient := newGRPCBrokerClient(conn)
57 broker := newGRPCBroker(brokerGRPCClient, c.config.TLSConfig)
58 go broker.Run()
59 go brokerGRPCClient.StartStream()
60
61 return &GRPCClient{
62 Conn: conn,
63 Plugins: c.config.Plugins,
64 doneCtx: doneCtx,
65 broker: broker,
66 }, nil
67}
68
69// GRPCClient connects to a GRPCServer over gRPC to dispense plugin types.
70type GRPCClient struct {
71 Conn *grpc.ClientConn
72 Plugins map[string]Plugin
73
74 doneCtx context.Context
75 broker *GRPCBroker
76}
77
78// ClientProtocol impl.
79func (c *GRPCClient) Close() error {
80 c.broker.Close()
81 return c.Conn.Close()
82}
83
84// ClientProtocol impl.
85func (c *GRPCClient) Dispense(name string) (interface{}, error) {
86 raw, ok := c.Plugins[name]
87 if !ok {
88 return nil, fmt.Errorf("unknown plugin type: %s", name)
89 }
90
91 p, ok := raw.(GRPCPlugin)
92 if !ok {
93 return nil, fmt.Errorf("plugin %q doesn't support gRPC", name)
94 }
95
96 return p.GRPCClient(c.doneCtx, c.broker, c.Conn)
97}
98
99// ClientProtocol impl.
100func (c *GRPCClient) Ping() error {
101 client := grpc_health_v1.NewHealthClient(c.Conn)
102 _, err := client.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{
103 Service: GRPCServiceName,
104 })
105
106 return err
107}