From 42fd236048176f1fb0b1c6e09b6df5a9faf388da Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Mon, 26 Dec 2022 15:49:38 -0600 Subject: [PATCH 1/7] Sentry Interceptors --- pkg/utils/sentry/config.go | 7 ++- pkg/utils/sentry/interceptors.go | 95 ++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 pkg/utils/sentry/interceptors.go diff --git a/pkg/utils/sentry/config.go b/pkg/utils/sentry/config.go index 9c4c492c2..92a750cbf 100644 --- a/pkg/utils/sentry/config.go +++ b/pkg/utils/sentry/config.go @@ -13,7 +13,10 @@ type Config struct { Environment string `split_words:"true"` Release string `split_words:"true"` TrackPerformance bool `split_words:"true" default:"false"` - SampleRate float64 `split_words:"true" default:"1.0"` + SampleRate float64 `split_words:"true" default:"0.85"` + Service string `split_words:"true"` + ReportErrors bool `split_words:"true" default:"false"` + Repanic bool `split_words:"true" default:"false"` Debug bool `default:"false"` } @@ -30,7 +33,7 @@ func (c Config) UsePerformanceTracking() bool { func (c Config) Validate() error { // If Sentry is enabled then the envionment must be set. if c.UseSentry() && c.Environment == "" { - return errors.New("invalid configuration: envrionment must be configured when Sentry is enabled") + return errors.New("invalid configuration: environment must be configured when Sentry is enabled") } return nil } diff --git a/pkg/utils/sentry/interceptors.go b/pkg/utils/sentry/interceptors.go new file mode 100644 index 000000000..6e9ab1775 --- /dev/null +++ b/pkg/utils/sentry/interceptors.go @@ -0,0 +1,95 @@ +package sentry + +import ( + "context" + + "github.com/getsentry/sentry-go" + "google.golang.org/grpc" +) + +// UnaryInterceptor for gRPC services that are using Sentry. Ensures that Sentry is used +// in a thread-safe manner and that performance, panics, and errors are correctly +// tracked with gRPC method names. +func UnaryInterceptor(conf Config) grpc.UnaryServerInterceptor { + trackPerformance := conf.UsePerformanceTracking() + reportErrors := conf.ReportErrors + serviceName := conf.Service + repanic := conf.Repanic + + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { + // Clone the hub for concurrent operations + hub := sentry.GetHubFromContext(ctx) + if hub == nil { + hub = sentry.CurrentHub().Clone() + ctx = sentry.SetHubOnContext(ctx, hub) + } + + if trackPerformance { + span := sentry.StartSpan(ctx, "grpc", sentry.TransactionName(info.FullMethod)) + defer span.Finish() + } + + hub.Scope().SetTransaction(info.FullMethod) + hub.Scope().SetTag("rpc", "unary") + if serviceName != "" { + hub.Scope().SetTag("service", serviceName) + } + + defer sentryRecovery(hub, ctx, repanic) + rep, err := handler(ctx, req) + if reportErrors && err != nil { + hub.CaptureException(err) + } + return rep, err + } +} + +// StreamInterceptor for gRPC services that are using Sentry. Ensures that Sentry is +// used in a thread-safe manner and that performance, panics, and errors are correctly +// tracked with gRPC method names. Streaming RPCs don't necessarily benefit from Sentry +// performance tracking, but it is helpful to see average durations. +func StreamInterceptor(conf Config) grpc.StreamServerInterceptor { + trackPerformance := conf.UsePerformanceTracking() + reportErrors := conf.ReportErrors + serviceName := conf.Service + repanic := conf.Repanic + + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { + // Clone the hub for concurrent operations + // TODO: this context is not updating the stream context. + ctx := stream.Context() + hub := sentry.GetHubFromContext(ctx) + if hub == nil { + hub = sentry.CurrentHub().Clone() + ctx = sentry.SetHubOnContext(ctx, hub) + } + + if trackPerformance { + span := sentry.StartSpan(ctx, "grpc", sentry.TransactionName(info.FullMethod)) + defer span.Finish() + } + + hub.Scope().SetTransaction(info.FullMethod) + hub.Scope().SetTag("rpc", "streaming") + if serviceName != "" { + hub.Scope().SetTag("service", serviceName) + } + + defer sentryRecovery(hub, ctx, repanic) + err = handler(srv, stream) + if reportErrors && err != nil { + hub.CaptureException(err) + } + + return err + } +} + +func sentryRecovery(hub *sentry.Hub, ctx context.Context, repanic bool) { + if err := recover(); err != nil { + hub.RecoverWithContext(ctx, err) + if repanic { + panic(err) + } + } +} From 570b4756d98790bb8dbaff67c287c849908b4ebb Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Mon, 26 Dec 2022 17:15:46 -0600 Subject: [PATCH 2/7] decompose grpc interceptors --- pkg/trtl/interceptor.go | 239 +++++-------------------- pkg/trtl/interceptor_test.go | 12 +- pkg/trtl/server.go | 4 +- pkg/utils/interceptors/logging.go | 119 ++++++++++++ pkg/utils/interceptors/logging_test.go | 25 +++ pkg/utils/interceptors/maintenance.go | 30 ++++ pkg/utils/interceptors/mtls.go | 109 +++++++++++ pkg/utils/interceptors/recovery.go | 60 +++++++ 8 files changed, 394 insertions(+), 204 deletions(-) create mode 100644 pkg/utils/interceptors/logging.go create mode 100644 pkg/utils/interceptors/logging_test.go create mode 100644 pkg/utils/interceptors/maintenance.go create mode 100644 pkg/utils/interceptors/mtls.go create mode 100644 pkg/utils/interceptors/recovery.go diff --git a/pkg/trtl/interceptor.go b/pkg/trtl/interceptor.go index cb50ce300..ec66271d9 100644 --- a/pkg/trtl/interceptor.go +++ b/pkg/trtl/interceptor.go @@ -1,216 +1,63 @@ package trtl import ( - "context" - "crypto/x509" - "crypto/x509/pkix" - "errors" - "fmt" - "net" - "runtime/debug" - "time" - - "github.com/getsentry/sentry-go" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" + "github.com/trisacrypto/directory/pkg/utils/interceptors" + sentryutil "github.com/trisacrypto/directory/pkg/utils/sentry" "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/peer" - status "google.golang.org/grpc/status" ) -type ContextKey string - -// PeerInfo stores information about the identity of a remote peer. -type PeerInfo struct { - Name *pkix.Name - DNSNames []string - IPAddresses []net.IP -} - -// The interceptor intercepts incoming gRPC requests and adds remote peer information to the context. -func (t *Server) interceptor(ctx context.Context, in interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (out interface{}, err error) { - // Track how long the method takes to execute. - start := time.Now() - panicked := true - - // Set the service tag - if t.conf.Sentry.UseSentry() { - sentry.CurrentHub().Scope().SetTag("service", "trtl") - } - - // Recover from panics in the handler. - defer func() { - if r := recover(); r != nil || panicked { - if t.conf.Sentry.UseSentry() { - sentry.CurrentHub().Recover(r) - } - log.WithLevel(zerolog.PanicLevel). - Err(fmt.Errorf("%v", r)). - Str("stack_trace", string(debug.Stack())). - Msg("trtl server has recovered from a panic") - err = status.Error(codes.Internal, "an unhandled exception occurred") - } - }() - - // Check if we're in maintenance mode - status method should still return a full response - if t.conf.Maintenance && info.FullMethod != "/trtl.v1.Trtl/Status" { - err = status.Error(codes.Unavailable, "the trtl service is currently in maintenance mode") - log.Trace().Err(err).Str("method", info.FullMethod).Msg("trtl service unavailable during maintenance mode") - - panicked = false - return nil, err - } +const statusMethod = "/trtl.v1.Trtl/Status" - // Fetch peer information from the TLS info if we're not in insecure mode. - if !t.conf.MTLS.Insecure { - var peer *PeerInfo - if peer, err = PeerFromTLS(ctx); err != nil { - err = status.Error(codes.Unauthenticated, "unable to retrieve authenticated peer information") - log.Warn().Err(err).Str("method", info.FullMethod).Msg("unauthenticated access detected") +// Prepares the interceptors (middleware) for the unary RPC endpoints of the server. +// The first interceptor will be the outer-most handler and the last will be the +// inner-most wrapper around the final handler. All unary interceptors returned by this +// method should be changed using grpc.ChaingUnaryInterceptor(). +func (t *Server) UnaryInterceptors() []grpc.UnaryServerInterceptor { + // Prepare Sentry configuration + // NOTE: this will override any user-configured settings + t.conf.Sentry.Service = "trtl" + t.conf.Sentry.Repanic = true - panicked = false - return nil, err + // If we're in maintenance mode, only return maintenance and recovery + if t.conf.Maintenance { + return []grpc.UnaryServerInterceptor{ + interceptors.UnaryRecovery(), + interceptors.UnaryMaintenance(statusMethod), } - - // Add peer information to the context. - ctx = context.WithValue(ctx, ContextKey("peer"), peer) } - // Call the handler to finalize the request and get the response. - var span *sentry.Span - if t.conf.Sentry.UsePerformanceTracking() { - span = sentry.StartSpan(ctx, "grpc handler", sentry.TransactionName(info.FullMethod)) - } - out, err = handler(ctx, in) - if t.conf.Sentry.UsePerformanceTracking() { - span.Finish() + // Return Unary interceptors + return []grpc.UnaryServerInterceptor{ + interceptors.UnaryLogging(), + interceptors.UnaryRecovery(), + sentryutil.UnaryInterceptor(t.conf.Sentry), + interceptors.UnaryMTLS(), } - - // Log with zerolog - checkout grpclog.LoggerV2 for default logging. - log.Debug(). - Err(err). - Str("method", info.FullMethod). - Str("latency", time.Since(start).String()). - Msg("gRPC request complete") - - panicked = false - return out, err } -// The streamInterceptor intercepts incoming gRPC streaming requests and adds remote -// peer information to the context, performing maintenance mode checks and panic recovery. -func (t *Server) streamInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { - // Track how long the method takes to execute - start := time.Now() - panicked := true - - // Set the service tag for sentry - if t.conf.Sentry.UseSentry() { - sentry.CurrentHub().Scope().SetTag("service", "trtl") - } - - // Recover from panics in the handler - defer func() { - if r := recover(); r != nil || panicked { - if t.conf.Sentry.UseSentry() { - sentry.CurrentHub().Recover(r) - } - log.WithLevel(zerolog.PanicLevel). - Err(fmt.Errorf("%v", r)). - Str("stack_trace", string(debug.Stack())). - Msg("trtl server has recovered from a panic") - err = status.Error(codes.Internal, "an unhandled exception occurred") - } - }() - - // Check if we're in maintenance mode -- no streaming method should be available +// Prepares the interceptors (middleware) for the stream RPC endpoints of the server. +// The first interceptor will be the outer-most handler and the last will be the +// inner-most wrapper around the final handler. All stream interceptors returned by this +// method should be changed using grpc.ChaingStreamInterceptor(). +func (t *Server) StreamInterceptors() []grpc.StreamServerInterceptor { + // Prepare Sentry configuration + // NOTE: this will override any user-configured settings + t.conf.Sentry.Service = "trtl" + t.conf.Sentry.Repanic = true + + // If we're in maintenance mode, only return maintenance and recovery if t.conf.Maintenance { - err = status.Error(codes.Unavailable, "the trtl service is currently in maintenance mode") - log.Trace().Err(err).Str("method", info.FullMethod).Msg("trtl service unavailable during maintenance mode") - - panicked = false - return err - } - - // Fetch peer information from the TLS info if we're not in insecure mode. - if !t.conf.MTLS.Insecure { - if _, err = PeerFromTLS(ss.Context()); err != nil { - err = status.Error(codes.Unauthenticated, "unable to retrieve authenticated peer information") - log.Warn().Err(err).Str("method", info.FullMethod).Msg("unauthenticated access detected") - - panicked = false - return err - } - - // TODO: add peer information to the context, this requires wrapping the ServerStream - // See: https://stackoverflow.com/questions/60982406/how-to-safely-add-values-to-grpc-serverstream-in-interceptor - } - - // Call the handler to execute the stream RPC - // NOTE: sentry performance tracking is not valid here since streams can take an - // arbitrarily long time to complete and minimizing latency is not necessarily desirable. - err = handler(srv, ss) - - // Log with zerolog - check grpclog.LoggerV2 for default logging - log.Debug(). - Err(err). - Str("method", info.FullMethod). - Str("duration", time.Since(start).String()). - Msg("grpc stream request complete") - - panicked = false - return err -} - -// PeerFromTLS looks up the TLSInfo from the incoming gRPC connection to retrieve -// information about the remote peer from the certificate. -func PeerFromTLS(ctx context.Context) (info *PeerInfo, err error) { - var ( - ok bool - gp *peer.Peer - tlsAuth credentials.TLSInfo - chains [][]*x509.Certificate - ) - - if gp, ok = peer.FromContext(ctx); !ok { - return nil, errors.New("no peer found in context") - } - - if tlsAuth, ok = gp.AuthInfo.(credentials.TLSInfo); !ok { - // If there is no mTLS information return nil peer info. - if gp.AuthInfo == nil { - return nil, nil + return []grpc.StreamServerInterceptor{ + interceptors.StreamRecovery(), + interceptors.StreamMaintenance(statusMethod), } - return nil, fmt.Errorf("unexpected peer transport credentials type: %T", gp.AuthInfo) } - chains = tlsAuth.State.VerifiedChains - if len(chains) == 0 { - return nil, errors.New("could not find certificate chain") + // Return Unary interceptors + return []grpc.StreamServerInterceptor{ + interceptors.StreamLogging(), + interceptors.StreamRecovery(), + sentryutil.StreamInterceptor(t.conf.Sentry), + interceptors.StreamMTLS(), } - - // Search for a valid peer certificate. - for _, c := range chains { - // Certificate chain should contain at least the peer certificate and the CA. - if len(c) >= 2 { - // The peer certificate is always first. - info = &PeerInfo{ - Name: &c[0].Subject, - DNSNames: c[0].DNSNames, - IPAddresses: []net.IP{}, - } - var addr net.IP - if addr = net.ParseIP(gp.Addr.String()); addr != nil { - // Only add the net.Addr if it's parseable - info.IPAddresses = append(info.IPAddresses, addr) - } - - info.IPAddresses = append(info.IPAddresses, c[0].IPAddresses...) - return info, nil - } - } - - return nil, errors.New("could not find peer certificate info") } diff --git a/pkg/trtl/interceptor_test.go b/pkg/trtl/interceptor_test.go index afd814804..6fc710191 100644 --- a/pkg/trtl/interceptor_test.go +++ b/pkg/trtl/interceptor_test.go @@ -5,9 +5,9 @@ import ( "crypto/x509/pkix" "net" - "github.com/trisacrypto/directory/pkg/trtl" "github.com/trisacrypto/directory/pkg/trtl/pb/v1" "github.com/trisacrypto/directory/pkg/trtl/peers/v1" + "github.com/trisacrypto/directory/pkg/utils/interceptors" ) // TestPeerFromTLS tests that the peerFromTLS function is able to extract peer info @@ -16,7 +16,7 @@ func (s *trtlTestSuite) TestPeerFromTLS() { require := s.Require() // TODO: We probably want to test more variations of the certificate. - expected := &trtl.PeerInfo{ + expected := &interceptors.PeerInfo{ Name: &pkix.Name{ Country: []string{"US"}, Organization: []string{"TRISA Development Client"}, @@ -41,12 +41,12 @@ func (s *trtlTestSuite) TestPeerFromTLS() { defer s.remote.CloseClient() // Create peer info that the RPC can write to - info := &trtl.PeerInfo{} + info := &interceptors.PeerInfo{} // Configure the remote peer to extract the peer info from the context s.remote.OnGet = func(ctx context.Context, req *pb.GetRequest) (*pb.GetReply, error) { // Extract the peer info from the context - info, err = trtl.PeerFromTLS(ctx) + info, err = interceptors.PeerFromTLS(ctx) require.NoError(err, "could not extract peer info from TLS") return &pb.GetReply{}, nil @@ -64,7 +64,7 @@ func (s *trtlTestSuite) TestPeerFromTLS() { // Configure the remote peer to extract the peer info from the context s.remote.OnAddPeers = func(ctx context.Context, req *peers.Peer) (*peers.PeersStatus, error) { // Extract the peer info from the context - info, err = trtl.PeerFromTLS(ctx) + info, err = interceptors.PeerFromTLS(ctx) require.NoError(err, "could not extract peer info from TLS") return &peers.PeersStatus{}, nil @@ -77,7 +77,7 @@ func (s *trtlTestSuite) TestPeerFromTLS() { } // checkPeerInfo checks that the peer info matches the expected one -func (s *trtlTestSuite) checkPeerInfo(expected *trtl.PeerInfo, actual *trtl.PeerInfo) { +func (s *trtlTestSuite) checkPeerInfo(expected *interceptors.PeerInfo, actual *interceptors.PeerInfo) { require := s.Require() // Remove the RDNSequence fields for comparison diff --git a/pkg/trtl/server.go b/pkg/trtl/server.go index d0e477f0b..983d6871b 100644 --- a/pkg/trtl/server.go +++ b/pkg/trtl/server.go @@ -94,8 +94,8 @@ func New(conf config.Config) (s *Server, err error) { // NOTE: It appears this must happen outside the struct initialization of the Server // or else the UnaryInterceptor doesn't capture conf when it when it creates the closure - opts = append(opts, grpc.UnaryInterceptor(s.interceptor)) - opts = append(opts, grpc.StreamInterceptor(s.streamInterceptor)) + opts = append(opts, grpc.ChainUnaryInterceptor(s.UnaryInterceptors()...)) + opts = append(opts, grpc.ChainStreamInterceptor(s.StreamInterceptors()...)) s.srv = grpc.NewServer(opts...) // NOTE: if we are *not* in maintenance mode, we must open the database before we diff --git a/pkg/utils/interceptors/logging.go b/pkg/utils/interceptors/logging.go new file mode 100644 index 000000000..820bd07cb --- /dev/null +++ b/pkg/utils/interceptors/logging.go @@ -0,0 +1,119 @@ +package interceptors + +import ( + "context" + "strings" + "time" + + "github.com/rs/zerolog/log" + "github.com/trisacrypto/directory/pkg" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// UnaryLogging handles generic logging of RPC methods to zerolog. +func UnaryLogging() grpc.UnaryServerInterceptor { + version := pkg.Version() + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { + // Parse the method for tags + service, method := ParseMethod(info.FullMethod) + + // Handle the request, tracing how long it takes. + start := time.Now() + rep, err := handler(ctx, req) + duration := time.Since(start) + code := status.Code(err) + + // Prepare log context for logging + logctx := log.With(). + Str("type", "unary"). + Str("service", service). + Str("method", method). + Str("version", version). + Uint32("code", uint32(code)). + Dur("duration", duration). + Logger() + + // Log based on the error code + switch code { + case codes.OK: + logctx.Info().Msg(info.FullMethod) + case codes.Unknown: + logctx.Error().Err(err).Msgf("unknown error handling %s", info.FullMethod) + case codes.Canceled, codes.InvalidArgument, codes.NotFound, codes.AlreadyExists, codes.Unauthenticated: + logctx.Info().Err(err).Msg(info.FullMethod) + case codes.DeadlineExceeded, codes.PermissionDenied, codes.ResourceExhausted, codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unavailable: + logctx.Warn().Err(err).Msg(info.FullMethod) + case codes.Unimplemented, codes.Internal, codes.DataLoss: + logctx.Error().Err(err).Str("full_method", info.FullMethod).Msg(err.Error()) + default: + logctx.Error().Err(err).Msgf("unhandled error code %s: %s", code, info.FullMethod) + } + + return rep, err + } +} + +// StreamLogging handles generic logging of RPC methods to zerolog. +func StreamLogging() grpc.StreamServerInterceptor { + version := pkg.Version() + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { + // Parse the method for tags + service, method := ParseMethod(info.FullMethod) + + // Handle the request and trace how long the request takes. + start := time.Now() + err = handler(srv, stream) + duration := time.Since(start) + code := status.Code(err) + + // Prepare log context for logging + logctx := log.With(). + Str("type", "stream"). + Str("stream_type", StreamType(info)). + Str("service", service). + Str("method", method). + Str("version", version). + Uint32("code", uint32(code)). + Dur("duration", duration). + Logger() + + switch code { + case codes.OK: + logctx.Info().Msg(info.FullMethod) + case codes.Unknown: + logctx.Error().Err(err).Msgf("unknown error handling %s", info.FullMethod) + case codes.Canceled, codes.InvalidArgument, codes.NotFound, codes.AlreadyExists, codes.Unauthenticated: + logctx.Info().Err(err).Msg(info.FullMethod) + case codes.DeadlineExceeded, codes.PermissionDenied, codes.ResourceExhausted, codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unavailable: + logctx.Warn().Err(err).Msg(info.FullMethod) + case codes.Unimplemented, codes.Internal, codes.DataLoss: + logctx.Error().Err(err).Str("full_method", info.FullMethod).Msg(err.Error()) + default: + logctx.Error().Err(err).Msgf("unhandled error code %s: %s", code, info.FullMethod) + } + return err + } +} + +func ParseMethod(method string) (string, string) { + method = strings.TrimPrefix(method, "/") // remove leading slash + if i := strings.Index(method, "/"); i >= 0 { + return method[:i], method[i+1:] + } + return "unknown", "unknown" +} + +func StreamType(info *grpc.StreamServerInfo) string { + if !info.IsClientStream && !info.IsServerStream { + return "unary" + } + if info.IsClientStream && !info.IsServerStream { + return "client_stream" + } + if !info.IsClientStream && info.IsServerStream { + return "server_stream" + } + return "bidirectional" +} diff --git a/pkg/utils/interceptors/logging_test.go b/pkg/utils/interceptors/logging_test.go new file mode 100644 index 000000000..566516db6 --- /dev/null +++ b/pkg/utils/interceptors/logging_test.go @@ -0,0 +1,25 @@ +package interceptors_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/trisacrypto/directory/pkg/utils/interceptors" +) + +func TestParseMethod(t *testing.T) { + tests := []struct { + FullMethod string + service string + rpc string + }{ + {"package.v1.Service/Echo", "package.v1.Service", "Echo"}, + {"Service/Echo", "Service", "Echo"}, + } + + for _, tc := range tests { + service, rpc := interceptors.ParseMethod(tc.FullMethod) + require.Equal(t, tc.service, service, "unexpected service parsed from %q", tc.FullMethod) + require.Equal(t, tc.rpc, rpc, "unexpected rpc parsed from %q", tc.FullMethod) + } +} diff --git a/pkg/utils/interceptors/maintenance.go b/pkg/utils/interceptors/maintenance.go new file mode 100644 index 000000000..f8ed85f1b --- /dev/null +++ b/pkg/utils/interceptors/maintenance.go @@ -0,0 +1,30 @@ +package interceptors + +import ( + "context" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// The maintenance interceptor only allows Status endpoint to be queried and returns a +// service unavailable error otherwise. +func UnaryMaintenance(statusEndpoint string) grpc.UnaryServerInterceptor { + // This interceptor will supercede all following interceptors. + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { + // Allow the Status endpoint through, otherwise return unavailable + if info.FullMethod == statusEndpoint { + return handler(ctx, req) + } + return nil, status.Error(codes.Unavailable, "service is currently in maintenance mode") + } +} + +// The stream maintenance interceptor simply returns an unavailable error. +func StreamMaintenance(statusEndpoint string) grpc.StreamServerInterceptor { + // This interceptor will supercede all following interceptors + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { + return status.Error(codes.Unavailable, "service is currently in maintenance mode") + } +} diff --git a/pkg/utils/interceptors/mtls.go b/pkg/utils/interceptors/mtls.go new file mode 100644 index 000000000..23fcc4f4f --- /dev/null +++ b/pkg/utils/interceptors/mtls.go @@ -0,0 +1,109 @@ +package interceptors + +import ( + "context" + "crypto/x509" + "crypto/x509/pkix" + "errors" + "fmt" + "net" + + "github.com/rs/zerolog/log" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/peer" + "google.golang.org/grpc/status" +) + +// UnaryMTLS adds authenticated peer info to the context and returns unauthenticated if +// that peer information is not available. +func UnaryMTLS() grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { + var peer *PeerInfo + if peer, err = PeerFromTLS(ctx); err != nil { + err = status.Error(codes.Unauthenticated, "unable to retrieve authenticated peer information") + log.Debug().Err(err).Str("method", info.FullMethod).Msg("unauthenticated access detected") + return nil, err + } + + // Add peer information to the context + ctx = context.WithValue(ctx, ContextKey("peer"), peer) + return handler(ctx, req) + } +} + +// StreamMTLS adds authenticated peer info to the context and returns unauthenticated if +// that peer information is not available. +func StreamMTLS() grpc.StreamServerInterceptor { + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { + // TODO: add peer information to the context, this requires wrapping the ServerStream + // See: https://stackoverflow.com/questions/60982406/how-to-safely-add-values-to-grpc-serverstream-in-interceptor + if _, err = PeerFromTLS(stream.Context()); err != nil { + err = status.Error(codes.Unauthenticated, "unable to retrieve authenticated peer information") + log.Debug().Err(err).Str("method", info.FullMethod).Msg("unauthenticated access detected") + return err + } + return handler(srv, stream) + } +} + +type ContextKey string + +// PeerInfo stores information about the identity of a remote peer. +type PeerInfo struct { + Name *pkix.Name + DNSNames []string + IPAddresses []net.IP +} + +// PeerFromTLS looks up the TLSInfo from the incoming gRPC connection to retrieve +// information about the remote peer from the certificate. +func PeerFromTLS(ctx context.Context) (info *PeerInfo, err error) { + var ( + ok bool + gp *peer.Peer + tlsAuth credentials.TLSInfo + chains [][]*x509.Certificate + ) + + if gp, ok = peer.FromContext(ctx); !ok { + return nil, errors.New("no peer found in context") + } + + if tlsAuth, ok = gp.AuthInfo.(credentials.TLSInfo); !ok { + // If there is no mTLS information return nil peer info. + if gp.AuthInfo == nil { + return nil, nil + } + return nil, fmt.Errorf("unexpected peer transport credentials type: %T", gp.AuthInfo) + } + + chains = tlsAuth.State.VerifiedChains + if len(chains) == 0 { + return nil, errors.New("could not find certificate chain") + } + + // Search for a valid peer certificate. + for _, c := range chains { + // Certificate chain should contain at least the peer certificate and the CA. + if len(c) >= 2 { + // The peer certificate is always first. + info = &PeerInfo{ + Name: &c[0].Subject, + DNSNames: c[0].DNSNames, + IPAddresses: []net.IP{}, + } + var addr net.IP + if addr = net.ParseIP(gp.Addr.String()); addr != nil { + // Only add the net.Addr if it's parseable + info.IPAddresses = append(info.IPAddresses, addr) + } + + info.IPAddresses = append(info.IPAddresses, c[0].IPAddresses...) + return info, nil + } + } + + return nil, errors.New("could not find peer certificate info") +} diff --git a/pkg/utils/interceptors/recovery.go b/pkg/utils/interceptors/recovery.go new file mode 100644 index 000000000..92ecb2c76 --- /dev/null +++ b/pkg/utils/interceptors/recovery.go @@ -0,0 +1,60 @@ +package interceptors + +import ( + "context" + "fmt" + "runtime/debug" + + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// Recovers a unary handler from a panic and converts the error into an internal error. +func UnaryRecovery() grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { + panicked := true + defer func() { + // NOTE: recover only works for the current go routine so panics in any + // go routine launched by the handler will not be recovered by this function + if r := recover(); r != nil || panicked { + log.WithLevel(zerolog.PanicLevel). + Err(fmt.Errorf("%v", r)). + Bool("panicked", panicked). + Str("stack_trace", string(debug.Stack())). + Msg("grpc server has recovered from a panic") + err = status.Error(codes.Internal, "an unhandled exception occurred") + } + }() + + rep, err := handler(ctx, req) + panicked = false + return rep, err + } +} + +// Recovers a stream handler from a panic and converts the error into an internal error. +func StreamRecovery() grpc.StreamServerInterceptor { + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { + panicked := true + + defer func() { + // NOTE: recover only works for the current go routine so panics in any + // go routine launched by the handler will not be recovered by this function + if r := recover(); r != nil || panicked { + log.WithLevel(zerolog.PanicLevel). + Err(fmt.Errorf("%v", r)). + Bool("panicked", panicked). + Str("stack_trace", string(debug.Stack())). + Msg("grpc server has recovered from a panic") + err = status.Error(codes.Internal, "an unhandled exception occurred") + } + }() + + err = handler(srv, stream) + panicked = false + return err + } +} From c0fe3330c58ecf7306144dc220e3a53dcecde21e Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Mon, 26 Dec 2022 17:34:30 -0600 Subject: [PATCH 3/7] finalize interceptors for trtl and gds --- pkg/gds/gds.go | 4 +- pkg/gds/interceptor.go | 170 +++++++++++-------------------- pkg/gds/members.go | 4 +- pkg/trtl/backup_test.go | 3 +- pkg/trtl/bench_test.go | 5 +- pkg/trtl/interceptor.go | 26 +++-- pkg/trtl/server_test.go | 7 +- pkg/utils/sentry/config.go | 3 +- pkg/utils/sentry/interceptors.go | 8 -- 9 files changed, 85 insertions(+), 145 deletions(-) diff --git a/pkg/gds/gds.go b/pkg/gds/gds.go index 7b5ccd197..7e64ee183 100644 --- a/pkg/gds/gds.go +++ b/pkg/gds/gds.go @@ -34,8 +34,8 @@ func NewGDS(svc *Service) (gds *GDS, err error) { // Initialize the gRPC server gds.srv = grpc.NewServer( - grpc.UnaryInterceptor(svc.unaryInterceptor), - grpc.StreamInterceptor(svc.streamInterceptor), + grpc.ChainUnaryInterceptor(svc.UnaryInterceptors()...), + grpc.ChainStreamInterceptor(svc.StreamInterceptors()...), ) api.RegisterTRISADirectoryServer(gds.srv, gds) return gds, nil diff --git a/pkg/gds/interceptor.go b/pkg/gds/interceptor.go index 53334675c..11b225b32 100644 --- a/pkg/gds/interceptor.go +++ b/pkg/gds/interceptor.go @@ -3,141 +3,93 @@ package gds import ( "context" "fmt" - "runtime/debug" - "time" "github.com/getsentry/sentry-go" "github.com/rs/zerolog" "github.com/rs/zerolog/log" members "github.com/trisacrypto/directory/pkg/gds/members/v1alpha1" + "github.com/trisacrypto/directory/pkg/utils/interceptors" + sentryutil "github.com/trisacrypto/directory/pkg/utils/sentry" api "github.com/trisacrypto/trisa/pkg/trisa/gds/api/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -func (s *Service) unaryInterceptor(ctx context.Context, in interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (out interface{}, err error) { - // Track how long the method takes to execute. - start := time.Now() - panicked := true +const statusMethod = "/trisa.gds.api.v1beta1.TRISADirectory/Status" - // Set the service tag - if s.conf.Sentry.UseSentry() { - var service string - switch info.Server.(type) { - case api.TRISADirectoryServer: - service = "gds" - case members.TRISAMembersServer: - service = "members" - default: - log.WithLevel(zerolog.PanicLevel).Err(fmt.Errorf("unknown service type: %T", info.Server)) - panicked = false - return nil, status.Error(codes.Unimplemented, "unknown service type for request") - } - sentry.CurrentHub().Scope().SetTag("service", service) - } +// Prepares the interceptors (middleware) for the unary RPC endpoints of the server. +// The first interceptor will be the outer-most handler and the last will be the +// inner-most wrapper around the final handler. All unary interceptors returned by this +// method should be changed using grpc.ChaingUnaryInterceptor(). +func (s *Service) UnaryInterceptors() []grpc.UnaryServerInterceptor { + // Prepare Sentry configuration + s.conf.Sentry.Repanic = true - // Recover from panics in the handler. - // See: https://github.com/grpc-ecosystem/go-grpc-middleware/blob/4705cb37b9857ad51b4c96ff5a2f3c60afe442cf/recovery/interceptors.go#L21-L37 - defer func() { - if r := recover(); r != nil || panicked { - if s.conf.Sentry.UseSentry() { - sentry.CurrentHub().Recover(r) - } - log.WithLevel(zerolog.PanicLevel). - Err(fmt.Errorf("%v", r)). - Str("stack_trace", string(debug.Stack())). - Msg("grpc server has recovered from a panic") - err = status.Error(codes.Internal, "an unhandled exception occurred") + // If we're in maintenance mode, only return maintenance and recovery + if s.conf.Maintenance { + return []grpc.UnaryServerInterceptor{ + interceptors.UnaryRecovery(), + interceptors.UnaryMaintenance(statusMethod), } - }() - - // Check if we're in maintenance mode - status method should still return a full response. - if s.conf.Maintenance && info.FullMethod != "/trisa.gds.api.v1beta1.TRISADirectory/Status" { - err = status.Error(codes.Unavailable, "the GDS service is currently in maintenance mode") - log.Trace().Err(err).Str("method", info.FullMethod).Msg("gds service unavailable during maintenance mode") - - panicked = false - return nil, err } - // Call the handler to finalize the request and get the response. - var span *sentry.Span - if s.conf.Sentry.UsePerformanceTracking() { - span = sentry.StartSpan(ctx, "grpc", sentry.TransactionName(info.FullMethod)) + // Return Unary interceptors + opts := []grpc.UnaryServerInterceptor{ + interceptors.UnaryLogging(), + interceptors.UnaryRecovery(), + sentryutil.UnaryInterceptor(s.conf.Sentry), + ServiceTag(), } - out, err = handler(ctx, in) - if s.conf.Sentry.UsePerformanceTracking() { - span.Finish() - } - - // Log with zerolog - checkout grpclog.LoggerV2 for default logging. - // TODO: add remote peer information if using mTLS - log.Debug(). - Err(err). - Str("method", info.FullMethod). - Str("latency", time.Since(start).String()). - Msg("gRPC request complete") - panicked = false - return out, err + return opts } -// The streamInterceptor intercepts incoming gRPC streaming requests and adds remote -// peer information to the context, performing maintenance mode checks and panic recovery. -func (s *Service) streamInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { - // Track how long the method takes to execute. - start := time.Now() - panicked := true +// Prepares the interceptors (middleware) for the stream RPC endpoints of the server. +// The first interceptor will be the outer-most handler and the last will be the +// inner-most wrapper around the final handler. All stream interceptors returned by this +// method should be changed using grpc.ChaingStreamInterceptor(). +func (s *Service) StreamInterceptors() []grpc.StreamServerInterceptor { + // Prepare Sentry configuration + s.conf.Sentry.Repanic = true - // Set the service tag - // TODO: set the type of the stream server to determine if the tag is gds or members - // Currently there are no streaming RPCs in our defined services (unreachable code) - if s.conf.Sentry.UseSentry() { - var service string - switch srv.(type) { - default: - log.WithLevel(zerolog.PanicLevel).Err(fmt.Errorf("unknown service type: %T", srv)) - return status.Error(codes.Unimplemented, "unknown service type for request") + // If we're in maintenance mode, only return maintenance and recovery + if s.conf.Maintenance { + return []grpc.StreamServerInterceptor{ + interceptors.StreamRecovery(), + interceptors.StreamMaintenance(statusMethod), } - sentry.CurrentHub().Scope().SetTag("service", service) } - // Recover from panics in the handler - defer func() { - if r := recover(); r != nil || panicked { - if s.conf.Sentry.UseSentry() { - sentry.CurrentHub().Recover(r) - } - log.WithLevel(zerolog.PanicLevel). - Err(fmt.Errorf("%v", r)). - Str("stack_trace", string(debug.Stack())). - Msg("trtl server has recovered from a panic") - err = status.Error(codes.Internal, "an unhandled exception occurred") - } - }() - - // Check if we're in maintenance mode -- no streaming method should be available - if s.conf.Maintenance { - err = status.Error(codes.Unavailable, "the GDS service is currently in maintenance mode") - log.Trace().Err(err).Str("method", info.FullMethod).Msg("gds service unavailable during maintenance mode") - - panicked = false - return err + // Return Unary interceptors + opts := []grpc.StreamServerInterceptor{ + interceptors.StreamLogging(), + interceptors.StreamRecovery(), + sentryutil.StreamInterceptor(s.conf.Sentry), } + return opts +} - // Call the handler to execute the stream RPC - // NOTE: sentry performance tracking is not valid here since streams can take an - // arbitrarily long time to complete and minimizing latency is not necessarily desirable. - err = handler(srv, ss) +func ServiceTag() grpc.UnaryServerInterceptor { + return func(ctx context.Context, in interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (out interface{}, err error) { + hub := sentry.GetHubFromContext(ctx) + if hub == nil { + hub = sentry.CurrentHub().Clone() + ctx = sentry.SetHubOnContext(ctx, hub) + } - // Log with zerolog - check grpclog.LoggerV2 for default logging - log.Debug(). - Err(err). - Str("method", info.FullMethod). - Str("duration", time.Since(start).String()). - Msg("grpc stream request complete") + var service string + switch info.Server.(type) { + case api.TRISADirectoryServer: + service = "gds" + case members.TRISAMembersServer: + service = "members" + default: + log.WithLevel(zerolog.PanicLevel).Err(fmt.Errorf("unknown service type: %T", info.Server)) + return nil, status.Error(codes.Unimplemented, "unknown service type for request") + } - panicked = false - return err + hub.Scope().SetTag("service", service) + return handler(ctx, in) + } } diff --git a/pkg/gds/members.go b/pkg/gds/members.go index 87df0e501..443e5da73 100644 --- a/pkg/gds/members.go +++ b/pkg/gds/members.go @@ -63,8 +63,8 @@ func NewMembers(svc *Service) (members *Members, err error) { } // Add the unary interceptor to the gRPC server - opts = append(opts, grpc.UnaryInterceptor(svc.unaryInterceptor)) - opts = append(opts, grpc.StreamInterceptor(svc.streamInterceptor)) + opts = append(opts, grpc.ChainUnaryInterceptor(svc.UnaryInterceptors()...)) + opts = append(opts, grpc.ChainStreamInterceptor(svc.StreamInterceptors()...)) // Initialize the gRPC server members.srv = grpc.NewServer(opts...) diff --git a/pkg/trtl/backup_test.go b/pkg/trtl/backup_test.go index 80f30ae94..16f823742 100644 --- a/pkg/trtl/backup_test.go +++ b/pkg/trtl/backup_test.go @@ -1,7 +1,6 @@ package trtl_test import ( - "io/ioutil" "os" "path/filepath" "sync" @@ -50,7 +49,7 @@ func (s *trtlTestSuite) TestBackupManager() { // Backup should be created require.DirExists(backupDir) - files, err := ioutil.ReadDir(backupDir) + files, err := os.ReadDir(backupDir) require.NoError(err) require.Len(files, 1, "wrong number of backups created") s.compareBackup(filepath.Join(conf.Storage, files[0].Name())) diff --git a/pkg/trtl/bench_test.go b/pkg/trtl/bench_test.go index e9512c507..701332df1 100644 --- a/pkg/trtl/bench_test.go +++ b/pkg/trtl/bench_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "os" "strconv" "testing" @@ -42,9 +41,7 @@ func setupTrtl(t testing.TB) (bench *trtlBench, err error) { bench = new(trtlBench) // Create a tmp directory for the database - if bench.tmpdb, err = ioutil.TempDir("", "trtldb-*"); err != nil { - return nil, err - } + bench.tmpdb = t.TempDir() // Manually create a configuration c := config.Config{ diff --git a/pkg/trtl/interceptor.go b/pkg/trtl/interceptor.go index ec66271d9..9cab399f2 100644 --- a/pkg/trtl/interceptor.go +++ b/pkg/trtl/interceptor.go @@ -2,7 +2,7 @@ package trtl import ( "github.com/trisacrypto/directory/pkg/utils/interceptors" - sentryutil "github.com/trisacrypto/directory/pkg/utils/sentry" + "github.com/trisacrypto/directory/pkg/utils/sentry" "google.golang.org/grpc" ) @@ -14,8 +14,6 @@ const statusMethod = "/trtl.v1.Trtl/Status" // method should be changed using grpc.ChaingUnaryInterceptor(). func (t *Server) UnaryInterceptors() []grpc.UnaryServerInterceptor { // Prepare Sentry configuration - // NOTE: this will override any user-configured settings - t.conf.Sentry.Service = "trtl" t.conf.Sentry.Repanic = true // If we're in maintenance mode, only return maintenance and recovery @@ -27,12 +25,16 @@ func (t *Server) UnaryInterceptors() []grpc.UnaryServerInterceptor { } // Return Unary interceptors - return []grpc.UnaryServerInterceptor{ + opts := []grpc.UnaryServerInterceptor{ interceptors.UnaryLogging(), interceptors.UnaryRecovery(), - sentryutil.UnaryInterceptor(t.conf.Sentry), - interceptors.UnaryMTLS(), + sentry.UnaryInterceptor(t.conf.Sentry), } + + if !t.conf.MTLS.Insecure { + opts = append(opts, interceptors.UnaryMTLS()) + } + return opts } // Prepares the interceptors (middleware) for the stream RPC endpoints of the server. @@ -41,8 +43,6 @@ func (t *Server) UnaryInterceptors() []grpc.UnaryServerInterceptor { // method should be changed using grpc.ChaingStreamInterceptor(). func (t *Server) StreamInterceptors() []grpc.StreamServerInterceptor { // Prepare Sentry configuration - // NOTE: this will override any user-configured settings - t.conf.Sentry.Service = "trtl" t.conf.Sentry.Repanic = true // If we're in maintenance mode, only return maintenance and recovery @@ -54,10 +54,14 @@ func (t *Server) StreamInterceptors() []grpc.StreamServerInterceptor { } // Return Unary interceptors - return []grpc.StreamServerInterceptor{ + opts := []grpc.StreamServerInterceptor{ interceptors.StreamLogging(), interceptors.StreamRecovery(), - sentryutil.StreamInterceptor(t.conf.Sentry), - interceptors.StreamMTLS(), + sentry.StreamInterceptor(t.conf.Sentry), + } + + if !t.conf.MTLS.Insecure { + opts = append(opts, interceptors.StreamMTLS()) } + return opts } diff --git a/pkg/trtl/server_test.go b/pkg/trtl/server_test.go index a86e85e87..64cf6ea94 100644 --- a/pkg/trtl/server_test.go +++ b/pkg/trtl/server_test.go @@ -7,7 +7,6 @@ import ( "errors" "flag" "fmt" - "io/ioutil" "net/url" "os" "path/filepath" @@ -194,9 +193,7 @@ func (s *trtlTestSuite) setupConfig() (err error) { } // Create a tmp directory for the database - if s.tmpdb, err = ioutil.TempDir("testdata", "trtldb-*"); err != nil { - return fmt.Errorf("could not create tmpdb: %s", err) - } + s.tmpdb = s.T().TempDir() // Create the configuration without loading it from the environment conf := mock.Config() @@ -384,7 +381,7 @@ func (s *trtlTestSuite) loadClientCredentials() (opts []grpc.DialOption, err err // comparative assertions in test code. func (s *trtlTestSuite) loadFixtures() (err error) { var fixtures []byte - if fixtures, err = ioutil.ReadFile("testdata/db.json"); err != nil { + if fixtures, err = os.ReadFile("testdata/db.json"); err != nil { return fmt.Errorf("could not read fixtures at testdata/db.json: %s", err) } diff --git a/pkg/utils/sentry/config.go b/pkg/utils/sentry/config.go index 92a750cbf..4154642da 100644 --- a/pkg/utils/sentry/config.go +++ b/pkg/utils/sentry/config.go @@ -14,9 +14,8 @@ type Config struct { Release string `split_words:"true"` TrackPerformance bool `split_words:"true" default:"false"` SampleRate float64 `split_words:"true" default:"0.85"` - Service string `split_words:"true"` ReportErrors bool `split_words:"true" default:"false"` - Repanic bool `split_words:"true" default:"false"` + Repanic bool `ignored:"true"` Debug bool `default:"false"` } diff --git a/pkg/utils/sentry/interceptors.go b/pkg/utils/sentry/interceptors.go index 6e9ab1775..dc6f7e541 100644 --- a/pkg/utils/sentry/interceptors.go +++ b/pkg/utils/sentry/interceptors.go @@ -13,7 +13,6 @@ import ( func UnaryInterceptor(conf Config) grpc.UnaryServerInterceptor { trackPerformance := conf.UsePerformanceTracking() reportErrors := conf.ReportErrors - serviceName := conf.Service repanic := conf.Repanic return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { @@ -31,9 +30,6 @@ func UnaryInterceptor(conf Config) grpc.UnaryServerInterceptor { hub.Scope().SetTransaction(info.FullMethod) hub.Scope().SetTag("rpc", "unary") - if serviceName != "" { - hub.Scope().SetTag("service", serviceName) - } defer sentryRecovery(hub, ctx, repanic) rep, err := handler(ctx, req) @@ -51,7 +47,6 @@ func UnaryInterceptor(conf Config) grpc.UnaryServerInterceptor { func StreamInterceptor(conf Config) grpc.StreamServerInterceptor { trackPerformance := conf.UsePerformanceTracking() reportErrors := conf.ReportErrors - serviceName := conf.Service repanic := conf.Repanic return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { @@ -71,9 +66,6 @@ func StreamInterceptor(conf Config) grpc.StreamServerInterceptor { hub.Scope().SetTransaction(info.FullMethod) hub.Scope().SetTag("rpc", "streaming") - if serviceName != "" { - hub.Scope().SetTag("service", serviceName) - } defer sentryRecovery(hub, ctx, repanic) err = handler(srv, stream) From 9bf8dd2ae78ec678edd432cc2edc0a337148473e Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Mon, 26 Dec 2022 17:38:26 -0600 Subject: [PATCH 4/7] fix typo in tests --- pkg/utils/sentry/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/utils/sentry/config_test.go b/pkg/utils/sentry/config_test.go index 423c85692..0a4201835 100644 --- a/pkg/utils/sentry/config_test.go +++ b/pkg/utils/sentry/config_test.go @@ -22,7 +22,7 @@ func TestSentryConfigValidation(t *testing.T) { // If Sentry is enabled, then the environment is required conf.DSN = "https://something.ingest.sentry.io" err = conf.Validate() - require.EqualError(t, err, "invalid configuration: envrionment must be configured when Sentry is enabled") + require.EqualError(t, err, "invalid configuration: environment must be configured when Sentry is enabled") conf.Environment = "test" err = conf.Validate() From 72b0af1efd2dd7e5bcdd9f29138fa87db9b264ef Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Mon, 26 Dec 2022 17:52:25 -0600 Subject: [PATCH 5/7] fix tests --- pkg/trtl/bench_test.go | 2 +- pkg/trtl/server_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/trtl/bench_test.go b/pkg/trtl/bench_test.go index 701332df1..8a5b8ea9d 100644 --- a/pkg/trtl/bench_test.go +++ b/pkg/trtl/bench_test.go @@ -41,7 +41,7 @@ func setupTrtl(t testing.TB) (bench *trtlBench, err error) { bench = new(trtlBench) // Create a tmp directory for the database - bench.tmpdb = t.TempDir() + bench.tmpdb = os.TempDir() // Manually create a configuration c := config.Config{ diff --git a/pkg/trtl/server_test.go b/pkg/trtl/server_test.go index 64cf6ea94..625cb4ed8 100644 --- a/pkg/trtl/server_test.go +++ b/pkg/trtl/server_test.go @@ -193,7 +193,7 @@ func (s *trtlTestSuite) setupConfig() (err error) { } // Create a tmp directory for the database - s.tmpdb = s.T().TempDir() + s.tmpdb = os.TempDir() // Create the configuration without loading it from the environment conf := mock.Config() From 6cc0d1cdf545032281203cb29189feeb7b9d065e Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Tue, 27 Dec 2022 16:14:02 -0600 Subject: [PATCH 6/7] fix tests --- go.mod | 12 +++++------- go.sum | 29 +---------------------------- pkg/trtl/bench_test.go | 4 +++- pkg/trtl/server_test.go | 4 +++- 4 files changed, 12 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index 33ce876ed..65ff3532d 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/google/uuid v1.3.0 github.com/googleapis/gax-go v1.0.3 github.com/hashicorp/go-multierror v1.1.1 + github.com/hashicorp/golang-lru v0.5.4 github.com/joho/godotenv v1.4.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/mroth/weightedrand v0.4.1 @@ -26,10 +27,14 @@ require ( github.com/sendgrid/sendgrid-go v3.11.1+incompatible github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 github.com/stretchr/testify v1.8.1 + github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a + github.com/swaggo/gin-swagger v1.5.3 + github.com/swaggo/swag v1.8.7 github.com/syndtr/goleveldb v1.0.0 github.com/trisacrypto/trisa v0.3.5 github.com/urfave/cli v1.22.9 github.com/urfave/cli/v2 v2.10.3 + golang.org/x/net v0.2.0 google.golang.org/api v0.85.0 google.golang.org/genproto v0.0.0-20220627151210-f754eecb4be7 google.golang.org/grpc v1.47.0 @@ -43,9 +48,7 @@ require ( cloud.google.com/go/iam v0.3.0 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/KyleBanks/depth v1.2.1 // indirect - github.com/PuerkitoBio/purell v1.2.0 // indirect github.com/PuerkitoBio/rehttp v1.1.0 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect @@ -66,7 +69,6 @@ require ( github.com/google/go-cmp v0.5.8 // indirect github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.15.6 // indirect @@ -88,15 +90,11 @@ require ( github.com/prometheus/procfs v0.7.3 // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect - github.com/swaggo/gin-swagger v1.5.3 // indirect - github.com/swaggo/swag v1.8.7 // indirect github.com/ugorji/go/codec v1.2.7 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opencensus.io v0.23.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.2.0 // indirect golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect golang.org/x/text v0.4.0 // indirect golang.org/x/tools v0.3.0 // indirect diff --git a/go.sum b/go.sum index b88f5885b..12acf2807 100644 --- a/go.sum +++ b/go.sum @@ -80,11 +80,8 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.2.0 h1:/Jdm5QfyM8zdlqT6WVZU4cfP23sot6CEHA4CS49Ezig= -github.com/PuerkitoBio/purell v1.2.0/go.mod h1:OhLRTaaIzhvIyofkJfB24gokC7tM42Px5UhoT32THBk= github.com/PuerkitoBio/rehttp v1.1.0 h1:JFZ7OeK+hbJpTxhNB0NDZT47AuXqCU0Smxfjtph7/Rs= github.com/PuerkitoBio/rehttp v1.1.0/go.mod h1:LUwKPoDbDIA2RL5wYZCNsQ90cx4OJ4AWBmq6KzWZL1s= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= @@ -196,6 +193,7 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= +github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -245,8 +243,6 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= -github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -254,7 +250,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78 github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -382,8 +377,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru v1.0.1 h1:5KzQ9DWj9u/NZIuatPgGU/H7bIxFbUta+iD5OQ/aLxo= -github.com/hashicorp/golang-lru v1.0.1/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= @@ -476,7 +469,6 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -531,8 +523,6 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9 github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= -github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -624,9 +614,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q= -github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -643,7 +630,6 @@ github.com/trisacrypto/trisa v0.3.5 h1:aRn6vSJ/LFc6e0lFy1vxdZfQHIak9VQpu9Ny//q99 github.com/trisacrypto/trisa v0.3.5/go.mod h1:5VC6uJBIyiPreZfR67Mri6+CVXIuVuFZwTPromBPi9g= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= @@ -700,8 +686,6 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -751,8 +735,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -810,8 +792,6 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -847,7 +827,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -936,8 +915,6 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810 h1:rHZQSjJdAI4Xf5Qzeh2bBc5YJIkPFVM6oDtMFYmgws0= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -952,7 +929,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -1022,8 +998,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1219,7 +1193,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/pkg/trtl/bench_test.go b/pkg/trtl/bench_test.go index 8a5b8ea9d..a7d4c0d5e 100644 --- a/pkg/trtl/bench_test.go +++ b/pkg/trtl/bench_test.go @@ -41,7 +41,9 @@ func setupTrtl(t testing.TB) (bench *trtlBench, err error) { bench = new(trtlBench) // Create a tmp directory for the database - bench.tmpdb = os.TempDir() + if bench.tmpdb, err = os.MkdirTemp("", "trtldb-*"); err != nil { + return nil, fmt.Errorf("could not create tmpdb: %w", err) + } // Manually create a configuration c := config.Config{ diff --git a/pkg/trtl/server_test.go b/pkg/trtl/server_test.go index 625cb4ed8..ae5e2cd21 100644 --- a/pkg/trtl/server_test.go +++ b/pkg/trtl/server_test.go @@ -193,7 +193,9 @@ func (s *trtlTestSuite) setupConfig() (err error) { } // Create a tmp directory for the database - s.tmpdb = os.TempDir() + if s.tmpdb, err = os.MkdirTemp("", "trtldb-*"); err != nil { + return fmt.Errorf("could not create tmpdb: %w", err) + } // Create the configuration without loading it from the environment conf := mock.Config() From a443f520477b0fe62d2b5e83537f5d7156583965 Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Tue, 27 Dec 2022 16:18:59 -0600 Subject: [PATCH 7/7] respond to feedback --- pkg/gds/interceptor.go | 6 +++--- pkg/trtl/interceptor.go | 6 +++--- pkg/utils/interceptors/mtls.go | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/gds/interceptor.go b/pkg/gds/interceptor.go index 11b225b32..63d82fbcf 100644 --- a/pkg/gds/interceptor.go +++ b/pkg/gds/interceptor.go @@ -21,7 +21,7 @@ const statusMethod = "/trisa.gds.api.v1beta1.TRISADirectory/Status" // Prepares the interceptors (middleware) for the unary RPC endpoints of the server. // The first interceptor will be the outer-most handler and the last will be the // inner-most wrapper around the final handler. All unary interceptors returned by this -// method should be changed using grpc.ChaingUnaryInterceptor(). +// method should be chained using grpc.ChainUnaryInterceptor(). func (s *Service) UnaryInterceptors() []grpc.UnaryServerInterceptor { // Prepare Sentry configuration s.conf.Sentry.Repanic = true @@ -48,7 +48,7 @@ func (s *Service) UnaryInterceptors() []grpc.UnaryServerInterceptor { // Prepares the interceptors (middleware) for the stream RPC endpoints of the server. // The first interceptor will be the outer-most handler and the last will be the // inner-most wrapper around the final handler. All stream interceptors returned by this -// method should be changed using grpc.ChaingStreamInterceptor(). +// method should be chained using grpc.ChainStreamInterceptor(). func (s *Service) StreamInterceptors() []grpc.StreamServerInterceptor { // Prepare Sentry configuration s.conf.Sentry.Repanic = true @@ -61,7 +61,7 @@ func (s *Service) StreamInterceptors() []grpc.StreamServerInterceptor { } } - // Return Unary interceptors + // Return Stream interceptors opts := []grpc.StreamServerInterceptor{ interceptors.StreamLogging(), interceptors.StreamRecovery(), diff --git a/pkg/trtl/interceptor.go b/pkg/trtl/interceptor.go index 9cab399f2..4caf6e387 100644 --- a/pkg/trtl/interceptor.go +++ b/pkg/trtl/interceptor.go @@ -11,7 +11,7 @@ const statusMethod = "/trtl.v1.Trtl/Status" // Prepares the interceptors (middleware) for the unary RPC endpoints of the server. // The first interceptor will be the outer-most handler and the last will be the // inner-most wrapper around the final handler. All unary interceptors returned by this -// method should be changed using grpc.ChaingUnaryInterceptor(). +// method should be chained using grpc.ChainUnaryInterceptor(). func (t *Server) UnaryInterceptors() []grpc.UnaryServerInterceptor { // Prepare Sentry configuration t.conf.Sentry.Repanic = true @@ -40,7 +40,7 @@ func (t *Server) UnaryInterceptors() []grpc.UnaryServerInterceptor { // Prepares the interceptors (middleware) for the stream RPC endpoints of the server. // The first interceptor will be the outer-most handler and the last will be the // inner-most wrapper around the final handler. All stream interceptors returned by this -// method should be changed using grpc.ChaingStreamInterceptor(). +// method should be chained using grpc.ChainStreamInterceptor(). func (t *Server) StreamInterceptors() []grpc.StreamServerInterceptor { // Prepare Sentry configuration t.conf.Sentry.Repanic = true @@ -53,7 +53,7 @@ func (t *Server) StreamInterceptors() []grpc.StreamServerInterceptor { } } - // Return Unary interceptors + // Return Stream interceptors opts := []grpc.StreamServerInterceptor{ interceptors.StreamLogging(), interceptors.StreamRecovery(), diff --git a/pkg/utils/interceptors/mtls.go b/pkg/utils/interceptors/mtls.go index 23fcc4f4f..c61eeea37 100644 --- a/pkg/utils/interceptors/mtls.go +++ b/pkg/utils/interceptors/mtls.go @@ -16,8 +16,8 @@ import ( "google.golang.org/grpc/status" ) -// UnaryMTLS adds authenticated peer info to the context and returns unauthenticated if -// that peer information is not available. +// UnaryMTLS adds authenticated peer info to the context and returns an unauthenticated +// error if that peer information is not available. func UnaryMTLS() grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) { var peer *PeerInfo @@ -33,8 +33,8 @@ func UnaryMTLS() grpc.UnaryServerInterceptor { } } -// StreamMTLS adds authenticated peer info to the context and returns unauthenticated if -// that peer information is not available. +// StreamMTLS adds authenticated peer info to the context and returns an unauthenticated +// error if that peer information is not available. func StreamMTLS() grpc.StreamServerInterceptor { return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) { // TODO: add peer information to the context, this requires wrapping the ServerStream