grpc_client.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package plugin
  2. import (
  3. "fmt"
  4. "golang.org/x/net/context"
  5. "google.golang.org/grpc"
  6. "google.golang.org/grpc/credentials"
  7. "google.golang.org/grpc/health/grpc_health_v1"
  8. )
  9. // newGRPCClient creates a new GRPCClient. The Client argument is expected
  10. // to be successfully started already with a lock held.
  11. func newGRPCClient(c *Client) (*GRPCClient, error) {
  12. // Build dialing options.
  13. opts := make([]grpc.DialOption, 0, 5)
  14. // We use a custom dialer so that we can connect over unix domain sockets
  15. opts = append(opts, grpc.WithDialer(c.dialer))
  16. // go-plugin expects to block the connection
  17. opts = append(opts, grpc.WithBlock())
  18. // Fail right away
  19. opts = append(opts, grpc.FailOnNonTempDialError(true))
  20. // If we have no TLS configuration set, we need to explicitly tell grpc
  21. // that we're connecting with an insecure connection.
  22. if c.config.TLSConfig == nil {
  23. opts = append(opts, grpc.WithInsecure())
  24. } else {
  25. opts = append(opts, grpc.WithTransportCredentials(
  26. credentials.NewTLS(c.config.TLSConfig)))
  27. }
  28. // Connect. Note the first parameter is unused because we use a custom
  29. // dialer that has the state to see the address.
  30. conn, err := grpc.Dial("unused", opts...)
  31. if err != nil {
  32. return nil, err
  33. }
  34. return &GRPCClient{
  35. Conn: conn,
  36. Plugins: c.config.Plugins,
  37. }, nil
  38. }
  39. // GRPCClient connects to a GRPCServer over gRPC to dispense plugin types.
  40. type GRPCClient struct {
  41. Conn *grpc.ClientConn
  42. Plugins map[string]Plugin
  43. }
  44. // ClientProtocol impl.
  45. func (c *GRPCClient) Close() error {
  46. return c.Conn.Close()
  47. }
  48. // ClientProtocol impl.
  49. func (c *GRPCClient) Dispense(name string) (interface{}, error) {
  50. raw, ok := c.Plugins[name]
  51. if !ok {
  52. return nil, fmt.Errorf("unknown plugin type: %s", name)
  53. }
  54. p, ok := raw.(GRPCPlugin)
  55. if !ok {
  56. return nil, fmt.Errorf("plugin %q doesn't support gRPC", name)
  57. }
  58. return p.GRPCClient(c.Conn)
  59. }
  60. // ClientProtocol impl.
  61. func (c *GRPCClient) Ping() error {
  62. client := grpc_health_v1.NewHealthClient(c.Conn)
  63. _, err := client.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{
  64. Service: GRPCServiceName,
  65. })
  66. return err
  67. }