github.com/cilium/cilium@v1.16.2/pkg/hubble/server/server.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 package server 5 6 import ( 7 "crypto/tls" 8 "errors" 9 "fmt" 10 11 "github.com/sirupsen/logrus" 12 "google.golang.org/grpc" 13 "google.golang.org/grpc/credentials" 14 healthpb "google.golang.org/grpc/health/grpc_health_v1" 15 "google.golang.org/grpc/reflection" 16 17 observerpb "github.com/cilium/cilium/api/v1/observer" 18 peerpb "github.com/cilium/cilium/api/v1/peer" 19 recorderpb "github.com/cilium/cilium/api/v1/recorder" 20 "github.com/cilium/cilium/pkg/hubble/server/serveroption" 21 ) 22 23 var ( 24 errNoListener = errors.New("no listener configured") 25 errNoServerTLSConfig = errors.New("no server TLS config is set") 26 ) 27 28 // Server is hubble's gRPC server. 29 type Server struct { 30 log logrus.FieldLogger 31 srv *grpc.Server 32 opts serveroption.Options 33 } 34 35 // NewServer creates a new hubble gRPC server. 36 func NewServer(log logrus.FieldLogger, options ...serveroption.Option) (*Server, error) { 37 opts := serveroption.Options{} 38 for _, opt := range options { 39 if err := opt(&opts); err != nil { 40 return nil, fmt.Errorf("failed to apply option: %w", err) 41 } 42 } 43 if opts.Listener == nil { 44 return nil, errNoListener 45 } 46 if opts.ServerTLSConfig == nil && !opts.Insecure { 47 return nil, errNoServerTLSConfig 48 } 49 50 s := &Server{log: log, opts: opts} 51 if err := s.initGRPCServer(); err != nil { 52 return nil, err 53 } 54 return s, nil 55 } 56 57 func (s *Server) newGRPCServer() (*grpc.Server, error) { 58 var opts []grpc.ServerOption 59 for _, interceptor := range s.opts.GRPCUnaryInterceptors { 60 opts = append(opts, grpc.UnaryInterceptor(interceptor)) 61 } 62 for _, interceptor := range s.opts.GRPCStreamInterceptors { 63 opts = append(opts, grpc.StreamInterceptor(interceptor)) 64 } 65 if s.opts.ServerTLSConfig != nil { 66 // NOTE: gosec is unable to resolve the constant and warns about "TLS 67 // MinVersion too low". 68 tlsConfig := s.opts.ServerTLSConfig.ServerConfig(&tls.Config{ //nolint:gosec 69 MinVersion: serveroption.MinTLSVersion, 70 }) 71 opts = append(opts, grpc.Creds(credentials.NewTLS(tlsConfig))) 72 } 73 return grpc.NewServer(opts...), nil 74 } 75 76 func (s *Server) initGRPCServer() error { 77 srv, err := s.newGRPCServer() 78 if err != nil { 79 return err 80 } 81 if s.opts.HealthService != nil { 82 healthpb.RegisterHealthServer(srv, s.opts.HealthService) 83 } 84 if s.opts.ObserverService != nil { 85 observerpb.RegisterObserverServer(srv, s.opts.ObserverService) 86 } 87 if s.opts.PeerService != nil { 88 peerpb.RegisterPeerServer(srv, s.opts.PeerService) 89 } 90 if s.opts.RecorderService != nil { 91 recorderpb.RegisterRecorderServer(srv, s.opts.RecorderService) 92 } 93 reflection.Register(srv) 94 if s.opts.GRPCMetrics != nil { 95 s.opts.GRPCMetrics.InitializeMetrics(srv) 96 } 97 s.srv = srv 98 return nil 99 } 100 101 // Serve starts the hubble server and accepts new connections on the configured 102 // listener. Stop should be called to stop the server. 103 func (s *Server) Serve() error { 104 return s.srv.Serve(s.opts.Listener) 105 } 106 107 // Stop stops the hubble server. 108 func (s *Server) Stop() { 109 s.srv.Stop() 110 }