diff options
Diffstat (limited to 'vendor/github.com/hashicorp/go-plugin/grpc_client.go')
-rw-r--r-- | vendor/github.com/hashicorp/go-plugin/grpc_client.go | 107 |
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 @@ | |||
1 | package plugin | ||
2 | |||
3 | import ( | ||
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 | |||
15 | func 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. | ||
49 | func 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. | ||
70 | type GRPCClient struct { | ||
71 | Conn *grpc.ClientConn | ||
72 | Plugins map[string]Plugin | ||
73 | |||
74 | doneCtx context.Context | ||
75 | broker *GRPCBroker | ||
76 | } | ||
77 | |||
78 | // ClientProtocol impl. | ||
79 | func (c *GRPCClient) Close() error { | ||
80 | c.broker.Close() | ||
81 | return c.Conn.Close() | ||
82 | } | ||
83 | |||
84 | // ClientProtocol impl. | ||
85 | func (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. | ||
100 | func (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 | } | ||