mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 02:16:28 +02:00
109 lines
3 KiB
Go
109 lines
3 KiB
Go
package grpc
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"errors"
|
|
"net"
|
|
"os"
|
|
"os/signal"
|
|
"sync"
|
|
"syscall"
|
|
|
|
"github.com/pomerium/pomerium/internal/log"
|
|
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
"google.golang.org/grpc/keepalive"
|
|
)
|
|
|
|
// NewServer creates a new gRPC serve.
|
|
// It is the callers responsibility to close the resturned server.
|
|
func NewServer(opt *ServerOptions, registrationFn func(s *grpc.Server), wg *sync.WaitGroup) (*grpc.Server, error) {
|
|
if opt == nil {
|
|
opt = defaultServerOptions
|
|
} else {
|
|
opt.applyServerDefaults()
|
|
}
|
|
ln, err := net.Listen("tcp", opt.Addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
grpcOpts := []grpc.ServerOption{
|
|
grpc.StatsHandler(metrics.NewGRPCServerStatsHandler(opt.ServiceName)),
|
|
grpc.KeepaliveParams(opt.KeepaliveParams),
|
|
}
|
|
|
|
if len(opt.TLSCertificate) == 1 {
|
|
cert := credentials.NewServerTLSFromCert(&opt.TLSCertificate[0])
|
|
grpcOpts = append(grpcOpts, grpc.Creds(cert))
|
|
} else if !opt.InsecureServer {
|
|
return nil, errors.New("internal/grpc: unexpected number of certificates")
|
|
}
|
|
|
|
srv := grpc.NewServer(grpcOpts...)
|
|
registrationFn(srv)
|
|
log.Info().
|
|
Str("addr", opt.Addr).
|
|
Bool("insecure", opt.InsecureServer).
|
|
Str("service", opt.ServiceName).
|
|
Interface("grpc-service-info", srv.GetServiceInfo()).
|
|
Msg("internal/grpc: registered")
|
|
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
if err := srv.Serve(ln); err != grpc.ErrServerStopped {
|
|
log.Error().Str("addr", opt.Addr).Err(err).Msg("internal/grpc: unexpected shutdown")
|
|
}
|
|
}()
|
|
|
|
return srv, nil
|
|
}
|
|
|
|
// ServerOptions contains the configurations settings for a gRPC server.
|
|
type ServerOptions struct {
|
|
// Addr specifies the host and port on which the server should serve
|
|
// gRPC requests. If empty, ":443" is used.
|
|
Addr string
|
|
|
|
// TLS certificates to use, if any.
|
|
TLSCertificate []tls.Certificate
|
|
|
|
// InsecureServer when enabled disables all transport security.
|
|
// In this mode, Pomerium is susceptible to man-in-the-middle attacks.
|
|
// This should be used only for testing.
|
|
InsecureServer bool
|
|
|
|
// KeepaliveParams sets GRPC keepalive.ServerParameters
|
|
KeepaliveParams keepalive.ServerParameters
|
|
|
|
// ServiceName specifies the service name for telemetry exposition
|
|
ServiceName string
|
|
}
|
|
|
|
var defaultServerOptions = &ServerOptions{
|
|
Addr: ":443",
|
|
}
|
|
|
|
func (o *ServerOptions) applyServerDefaults() {
|
|
if o.Addr == "" {
|
|
o.Addr = defaultServerOptions.Addr
|
|
}
|
|
|
|
}
|
|
|
|
// Shutdown attempts to shut down the server when a os interrupt or sigterm
|
|
// signal are received without interrupting any
|
|
// active connections. Shutdown stops the server from
|
|
// accepting new connections and RPCs and blocks until all the pending RPCs are
|
|
// finished.
|
|
func Shutdown(srv *grpc.Server) {
|
|
sigint := make(chan os.Signal, 1)
|
|
signal.Notify(sigint, os.Interrupt)
|
|
signal.Notify(sigint, syscall.SIGTERM)
|
|
rec := <-sigint
|
|
log.Info().Str("signal", rec.String()).Msg("internal/grpc: shutting down servers")
|
|
srv.GracefulStop()
|
|
log.Info().Str("signal", rec.String()).Msg("internal/grpc: shut down servers")
|
|
}
|