2021-10-19 17:21:41 -04:00
package controller
import (
"context"
"math"
"net"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
2021-12-16 15:13:28 -08:00
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
2021-10-19 17:21:41 -04:00
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/hashicorp/boundary/globals"
2022-05-09 12:45:10 -07:00
"github.com/hashicorp/boundary/internal/daemon/controller/common"
"github.com/hashicorp/boundary/internal/daemon/controller/handlers"
2021-10-19 17:21:41 -04:00
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/kms"
2021-10-23 21:23:49 -04:00
"github.com/hashicorp/boundary/internal/observability/event"
2022-04-01 13:38:58 -04:00
"github.com/hashicorp/boundary/internal/types/subtypes"
2021-10-19 17:21:41 -04:00
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
)
const gatewayTarget = ""
2022-03-09 20:41:15 +00:00
type grpcServerListener interface {
2021-10-19 17:21:41 -04:00
net . Listener
Dial () ( net . Conn , error )
}
2022-03-09 20:41:15 +00:00
func gatewayDialOptions ( lis grpcServerListener ) [] grpc . DialOption {
2021-10-19 17:21:41 -04:00
return [] grpc . DialOption {
grpc . WithInsecure (),
grpc . WithContextDialer ( func ( context . Context , string ) ( net . Conn , error ) {
return lis . Dial ()
}),
}
}
2022-03-09 20:41:15 +00:00
func newGrpcGatewayMux () * runtime . ServeMux {
2021-10-19 17:21:41 -04:00
return runtime . NewServeMux (
runtime . WithMarshalerOption ( runtime . MIMEWildcard , & runtime . HTTPBodyMarshaler {
Marshaler : handlers . JSONMarshaler (),
}),
runtime . WithErrorHandler ( handlers . ErrorHandler ()),
runtime . WithForwardResponseOption ( handlers . OutgoingResponseFilter ),
)
}
2022-03-09 20:41:15 +00:00
// newGrpcServerListener will create an in-memory listener for the gRPC server.
func newGrpcServerListener () grpcServerListener {
buffer := globals . DefaultMaxRequestSize // seems like a reasonable size for the ring buffer, but then happily change the size if more info becomes available
return bufconn . Listen ( int ( buffer ))
}
func newGrpcServer (
2021-10-23 21:23:49 -04:00
ctx context . Context ,
iamRepoFn common . IamRepoFactory ,
authTokenRepoFn common . AuthTokenRepoFactory ,
serversRepoFn common . ServersRepoFactory ,
kms * kms . Kms ,
eventer * event . Eventer ,
) ( * grpc . Server , string , error ) {
2022-03-09 20:41:15 +00:00
const op = "controller.newGrpcServer"
2021-10-19 17:21:41 -04:00
ticket , err := db . NewPrivateId ( "gwticket" )
if err != nil {
return nil , "" , errors . Wrap ( ctx , err , op , errors . WithMsg ( "unable to generate gateway ticket" ))
}
2021-10-23 21:23:49 -04:00
requestCtxInterceptor , err := requestCtxInterceptor ( ctx , iamRepoFn , authTokenRepoFn , serversRepoFn , kms , ticket , eventer )
2021-10-19 17:21:41 -04:00
if err != nil {
return nil , "" , err
}
return grpc . NewServer (
grpc . MaxRecvMsgSize ( math . MaxInt32 ),
grpc . MaxSendMsgSize ( math . MaxInt32 ),
2021-10-23 21:23:49 -04:00
grpc . UnaryInterceptor (
grpc_middleware . ChainUnaryServer (
2022-04-01 13:38:58 -04:00
requestCtxInterceptor , // populated requestInfo from headers into the request ctx
2022-04-06 09:05:22 -04:00
errorInterceptor ( ctx ), // convert domain and api errors into headers for the http proxy
2022-04-01 13:38:58 -04:00
subtypes . AttributeTransformerInterceptor ( ctx ), // convert to/from generic attributes from/to subtype specific attributes
auditRequestInterceptor ( ctx ), // before we get started, audit the request
statusCodeInterceptor ( ctx ), // convert grpc codes into http status codes for the http proxy (can modify the resp)
auditResponseInterceptor ( ctx ), // as we finish, audit the response
2021-12-16 15:13:28 -08:00
grpc_recovery . UnaryServerInterceptor ( // recover from panics with a grpc internal error
grpc_recovery . WithRecoveryHandlerContext ( recoveryHandler ()),
),
2021-10-23 21:23:49 -04:00
),
),
2021-10-19 17:21:41 -04:00
), ticket , nil
}