]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/hashicorp/go-plugin/grpc_server.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / go-plugin / grpc_server.go
CommitLineData
15c0b25d
AP
1package plugin
2
3import (
4 "bytes"
5 "crypto/tls"
6 "encoding/json"
7 "fmt"
8 "io"
9 "net"
10
107c1cdb
ND
11 hclog "github.com/hashicorp/go-hclog"
12 "github.com/hashicorp/go-plugin/internal/plugin"
15c0b25d
AP
13 "google.golang.org/grpc"
14 "google.golang.org/grpc/credentials"
15 "google.golang.org/grpc/health"
16 "google.golang.org/grpc/health/grpc_health_v1"
17)
18
19// GRPCServiceName is the name of the service that the health check should
20// return as passing.
21const GRPCServiceName = "plugin"
22
23// DefaultGRPCServer can be used with the "GRPCServer" field for Server
24// as a default factory method to create a gRPC server with no extra options.
25func DefaultGRPCServer(opts []grpc.ServerOption) *grpc.Server {
26 return grpc.NewServer(opts...)
27}
28
29// GRPCServer is a ServerType implementation that serves plugins over
30// gRPC. This allows plugins to easily be written for other languages.
31//
32// The GRPCServer outputs a custom configuration as a base64-encoded
33// JSON structure represented by the GRPCServerConfig config structure.
34type GRPCServer struct {
35 // Plugins are the list of plugins to serve.
36 Plugins map[string]Plugin
37
38 // Server is the actual server that will accept connections. This
39 // will be used for plugin registration as well.
40 Server func([]grpc.ServerOption) *grpc.Server
41
42 // TLS should be the TLS configuration if available. If this is nil,
43 // the connection will not have transport security.
44 TLS *tls.Config
45
46 // DoneCh is the channel that is closed when this server has exited.
47 DoneCh chan struct{}
48
49 // Stdout/StderrLis are the readers for stdout/stderr that will be copied
50 // to the stdout/stderr connection that is output.
51 Stdout io.Reader
52 Stderr io.Reader
53
54 config GRPCServerConfig
55 server *grpc.Server
56 broker *GRPCBroker
107c1cdb
ND
57
58 logger hclog.Logger
15c0b25d
AP
59}
60
61// ServerProtocol impl.
62func (s *GRPCServer) Init() error {
63 // Create our server
64 var opts []grpc.ServerOption
65 if s.TLS != nil {
66 opts = append(opts, grpc.Creds(credentials.NewTLS(s.TLS)))
67 }
68 s.server = s.Server(opts)
69
70 // Register the health service
71 healthCheck := health.NewServer()
72 healthCheck.SetServingStatus(
73 GRPCServiceName, grpc_health_v1.HealthCheckResponse_SERVING)
74 grpc_health_v1.RegisterHealthServer(s.server, healthCheck)
75
76 // Register the broker service
77 brokerServer := newGRPCBrokerServer()
107c1cdb 78 plugin.RegisterGRPCBrokerServer(s.server, brokerServer)
15c0b25d
AP
79 s.broker = newGRPCBroker(brokerServer, s.TLS)
80 go s.broker.Run()
81
107c1cdb
ND
82 // Register the controller
83 controllerServer := &grpcControllerServer{
84 server: s,
85 }
86 plugin.RegisterGRPCControllerServer(s.server, controllerServer)
87
15c0b25d
AP
88 // Register all our plugins onto the gRPC server.
89 for k, raw := range s.Plugins {
90 p, ok := raw.(GRPCPlugin)
91 if !ok {
92 return fmt.Errorf("%q is not a GRPC-compatible plugin", k)
93 }
94
95 if err := p.GRPCServer(s.broker, s.server); err != nil {
107c1cdb 96 return fmt.Errorf("error registering %q: %s", k, err)
15c0b25d
AP
97 }
98 }
99
100 return nil
101}
102
103// Stop calls Stop on the underlying grpc.Server
104func (s *GRPCServer) Stop() {
105 s.server.Stop()
106}
107
108// GracefulStop calls GracefulStop on the underlying grpc.Server
109func (s *GRPCServer) GracefulStop() {
110 s.server.GracefulStop()
111}
112
113// Config is the GRPCServerConfig encoded as JSON then base64.
114func (s *GRPCServer) Config() string {
115 // Create a buffer that will contain our final contents
116 var buf bytes.Buffer
117
118 // Wrap the base64 encoding with JSON encoding.
119 if err := json.NewEncoder(&buf).Encode(s.config); err != nil {
120 // We panic since ths shouldn't happen under any scenario. We
121 // carefully control the structure being encoded here and it should
122 // always be successful.
123 panic(err)
124 }
125
126 return buf.String()
127}
128
129func (s *GRPCServer) Serve(lis net.Listener) {
107c1cdb
ND
130 defer close(s.DoneCh)
131 err := s.server.Serve(lis)
132 if err != nil {
133 s.logger.Error("grpc server", "error", err)
134 }
15c0b25d
AP
135}
136
137// GRPCServerConfig is the extra configuration passed along for consumers
138// to facilitate using GRPC plugins.
139type GRPCServerConfig struct {
140 StdoutAddr string `json:"stdout_addr"`
141 StderrAddr string `json:"stderr_addr"`
142}