StartGRPCServer starts a gRPC server listening on the given address. The server can be configured using the supplied opts, e.g., to register various Clouditor services. The server itself is started in a separate Go routine, therefore this function will NOT block.
(addr string, opts ...StartGRPCServerOption)
| 115 | // opts, e.g., to register various Clouditor services. The server itself is started in a separate Go routine, therefore |
| 116 | // this function will NOT block. |
| 117 | func StartGRPCServer(addr string, opts ...StartGRPCServerOption) (sock net.Listener, srv *Server, err error) { |
| 118 | // create a new socket for gRPC communication |
| 119 | sock, err = net.Listen("tcp", addr) |
| 120 | if err != nil { |
| 121 | return nil, nil, fmt.Errorf("could not listen: %w", err) |
| 122 | } |
| 123 | |
| 124 | var c config |
| 125 | |
| 126 | grpcLogger := logrus.New() |
| 127 | grpcLogger.Formatter = &formatter.GRPCFormatter{TextFormatter: logrus.TextFormatter{ForceColors: true}} |
| 128 | grpcLoggerEntry := grpcLogger.WithField("component", "grpc") |
| 129 | |
| 130 | c.grpcOpts = []grpc.ServerOption{ |
| 131 | grpc.ChainUnaryInterceptor( |
| 132 | grpc_ctxtags.UnaryServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)), |
| 133 | grpc_logrus.UnaryServerInterceptor(grpcLoggerEntry), |
| 134 | UnaryServerInterceptorWithFilter(&c, grpc_auth.UnaryServerInterceptor(c.ac.AuthFunc()), UnaryReflectionFilter, UnaryPublicEndpointFilter), |
| 135 | ), |
| 136 | grpc.ChainStreamInterceptor( |
| 137 | grpc_ctxtags.StreamServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)), |
| 138 | grpc_logrus.StreamServerInterceptor(grpcLoggerEntry), |
| 139 | StreamServerInterceptorWithFilter(&c, grpc_auth.StreamServerInterceptor(c.ac.AuthFunc()), StreamReflectionFilter, StreamPublicEndpointFilter), |
| 140 | ), |
| 141 | } |
| 142 | c.services = map[*grpc.ServiceDesc]any{} |
| 143 | |
| 144 | for _, o := range opts { |
| 145 | o(&c) |
| 146 | } |
| 147 | |
| 148 | srv = grpc.NewServer( |
| 149 | c.grpcOpts..., |
| 150 | ) |
| 151 | |
| 152 | // Register services |
| 153 | for sd, svc := range c.services { |
| 154 | srv.RegisterService(sd, svc) |
| 155 | } |
| 156 | |
| 157 | // Enable reflection |
| 158 | if c.reflection { |
| 159 | reflection.Register(srv) |
| 160 | } |
| 161 | |
| 162 | go func() { |
| 163 | // serve the gRPC socket |
| 164 | _ = srv.Serve(sock) |
| 165 | }() |
| 166 | |
| 167 | return sock, srv, nil |
| 168 | } |
| 169 | |
| 170 | // UnaryServerInterceptorWithFilter wraps a grpc.UnaryServerInterceptor and only invokes the interceptor, if the filter |
| 171 | // function does not return true. |