From cf6473feb9104584df347bdc42728b8dbc851bdf Mon Sep 17 00:00:00 2001 From: Brian Joerger Date: Thu, 24 Aug 2023 16:27:06 -0700 Subject: [PATCH] Add gRPC error interceptors to API client (#30578) * Move gRPC error intercetpors to api/utils/grpc/interceptors. * Use error interceptors in api client and mock server. * Apply suggestions from CR. * Unwrap FromGRPC errors in middleware. * Use gRPC auth service in tests instead of external example service. * It's gRPC!!! * Fix unit test. * Add error interceptor to proxy client. * Fix merge conflict. --- Makefile | 8 +- api/breaker/breaker.go | 2 +- api/client/accesslist/accesslist.go | 40 +- api/client/auditstreamer.go | 13 +- api/client/client.go | 564 +++++++++--------- api/client/inventory.go | 21 +- api/client/keepaliver.go | 8 +- api/client/mock_server_test.go | 3 + api/client/okta/okta.go | 27 +- api/client/proxy/client.go | 3 + .../proxy/transport/transportv1/client.go | 17 +- .../transport/transportv1/client_test.go | 3 + api/client/sessions.go | 17 +- api/client/streamwatcher.go | 7 +- api/client/userloginstate/userloginstate.go | 18 +- api/metadata/metadata.go | 10 +- api/utils/grpc/interceptors/errors.go | 87 +++ api/utils/grpc/interceptors/errors_test.go | 103 ++++ api/utils/grpc/stream/stream.go | 5 +- constants.go | 2 +- .../resources/plugins/teleport-gitlab.toml | 6 +- go.mod | 1 - go.sum | 2 - integrations/access/common/app.go | 2 +- integrations/access/jira/app.go | 2 +- integrations/access/jira/config.go | 4 +- integrations/access/opsgenie/app.go | 2 +- integrations/access/pagerduty/app.go | 2 +- integrations/access/pagerduty/config.go | 2 +- lib/auth/grpcserver.go | 20 +- lib/auth/grpcserver_test.go | 6 +- lib/auth/http_client.go | 2 +- lib/auth/keystore/gcp_kms_test.go | 5 +- lib/auth/middleware.go | 11 +- lib/backend/firestore/README.md | 2 +- lib/backend/firestore/firestorebk.go | 2 +- lib/client/api.go | 5 +- lib/client/identityfile/identity.go | 2 +- lib/config/fileconf.go | 4 +- lib/devicetrust/testenv/testenv.go | 10 +- lib/events/firestoreevents/README.md | 2 +- lib/joinserver/joinserver_test.go | 6 +- lib/observability/metrics/prometheus.go | 4 +- lib/proxy/peer/client.go | 4 +- lib/proxy/peer/interceptor.go | 4 +- lib/service/service.go | 15 +- lib/service/service_test.go | 6 +- lib/services/suite/suite.go | 2 +- .../transport/transportv1/transport_test.go | 9 +- lib/teleterm/apiserver/middleware.go | 2 +- lib/utils/grpc.go | 73 +-- lib/utils/grpc_test.go | 97 --- lib/utils/tls.go | 2 +- lib/web/apiserver_test.go | 9 +- web/packages/teleterm/README.md | 4 +- 55 files changed, 666 insertions(+), 623 deletions(-) create mode 100644 api/utils/grpc/interceptors/errors.go create mode 100644 api/utils/grpc/interceptors/errors_test.go delete mode 100644 lib/utils/grpc_test.go diff --git a/Makefile b/Makefile index e0c0c150b0d2..a3562a4a44c3 100644 --- a/Makefile +++ b/Makefile @@ -1218,7 +1218,7 @@ buf/installed: exit 1; \ fi -# grpc generates GRPC stubs from service definitions. +# grpc generates gRPC stubs from service definitions. # This target runs in the buildbox container. .PHONY: grpc grpc: @@ -1228,13 +1228,13 @@ else $(MAKE) grpc/host endif -# grpc/host generates GRPC stubs. +# grpc/host generates gRPC stubs. # Unlike grpc, this target runs locally. .PHONY: grpc/host grpc/host: protos/all @build.assets/genproto.sh -# protos-up-to-date checks if the generated GRPC stubs are up to date. +# protos-up-to-date checks if the generated gRPC stubs are up to date. # This target runs in the buildbox container. .PHONY: protos-up-to-date protos-up-to-date: @@ -1244,7 +1244,7 @@ else $(MAKE) protos-up-to-date/host endif -# protos-up-to-date/host checks if the generated GRPC stubs are up to date. +# protos-up-to-date/host checks if the generated gRPC stubs are up to date. # Unlike protos-up-to-date, this target runs locally. .PHONY: protos-up-to-date/host protos-up-to-date/host: must-start-clean/host grpc/host diff --git a/api/breaker/breaker.go b/api/breaker/breaker.go index 702dfa83a9f5..6000d8025d83 100644 --- a/api/breaker/breaker.go +++ b/api/breaker/breaker.go @@ -178,7 +178,7 @@ func NonNilErrorIsSuccess(_ interface{}, err error) bool { } // IsResponseSuccessful determines whether the error provided should be ignored by the circuit breaker. This checks -// for http status codes < 500 and a few unsuccessful grpc status codes. +// for http status codes < 500 and a few unsuccessful gRPC status codes. func IsResponseSuccessful(v interface{}, err error) bool { switch t := v.(type) { case nil: diff --git a/api/client/accesslist/accesslist.go b/api/client/accesslist/accesslist.go index da10119c5c52..1d89514f38bc 100644 --- a/api/client/accesslist/accesslist.go +++ b/api/client/accesslist/accesslist.go @@ -17,7 +17,7 @@ package accesslist import ( "context" - "github.com/gravitational/trace/trail" + "github.com/gravitational/trace" accesslistv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1" "github.com/gravitational/teleport/api/types/accesslist" @@ -41,7 +41,7 @@ func NewClient(grpcClient accesslistv1.AccessListServiceClient) *Client { func (c *Client) GetAccessLists(ctx context.Context) ([]*accesslist.AccessList, error) { resp, err := c.grpcClient.GetAccessLists(ctx, &accesslistv1.GetAccessListsRequest{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } accessLists := make([]*accesslist.AccessList, len(resp.AccessLists)) @@ -49,7 +49,7 @@ func (c *Client) GetAccessLists(ctx context.Context) ([]*accesslist.AccessList, var err error accessLists[i], err = conv.FromProto(accessList) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } } @@ -63,7 +63,7 @@ func (c *Client) ListAccessLists(ctx context.Context, pageSize int, nextToken st NextToken: nextToken, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } accessLists := make([]*accesslist.AccessList, len(resp.AccessLists)) @@ -71,7 +71,7 @@ func (c *Client) ListAccessLists(ctx context.Context, pageSize int, nextToken st var err error accessLists[i], err = conv.FromProto(accessList) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } } @@ -84,11 +84,11 @@ func (c *Client) GetAccessList(ctx context.Context, name string) (*accesslist.Ac Name: name, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } accessList, err := conv.FromProto(resp) - return accessList, trail.FromGRPC(err) + return accessList, trace.Wrap(err) } // UpsertAccessList creates or updates an access list resource. @@ -97,10 +97,10 @@ func (c *Client) UpsertAccessList(ctx context.Context, accessList *accesslist.Ac AccessList: conv.ToProto(accessList), }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } responseAccessList, err := conv.FromProto(resp) - return responseAccessList, trail.FromGRPC(err) + return responseAccessList, trace.Wrap(err) } // DeleteAccessList removes the specified access list resource. @@ -108,13 +108,13 @@ func (c *Client) DeleteAccessList(ctx context.Context, name string) error { _, err := c.grpcClient.DeleteAccessList(ctx, &accesslistv1.DeleteAccessListRequest{ Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllAccessLists removes all access lists. func (c *Client) DeleteAllAccessLists(ctx context.Context) error { _, err := c.grpcClient.DeleteAllAccessLists(ctx, &accesslistv1.DeleteAllAccessListsRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // ListAccessListMembers returns a paginated list of all access list members for an access list. @@ -125,7 +125,7 @@ func (c *Client) ListAccessListMembers(ctx context.Context, accessList string, p AccessList: accessList, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } members = make([]*accesslist.AccessListMember, len(resp.Members)) @@ -133,7 +133,7 @@ func (c *Client) ListAccessListMembers(ctx context.Context, accessList string, p var err error members[i], err = conv.FromMemberProto(accessList) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } } @@ -147,11 +147,11 @@ func (c *Client) GetAccessListMember(ctx context.Context, accessList string, mem MemberName: memberName, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } member, err := conv.FromMemberProto(resp) - return member, trail.FromGRPC(err) + return member, trace.Wrap(err) } // UpsertAccessListMember creates or updates an access list member resource. @@ -160,10 +160,10 @@ func (c *Client) UpsertAccessListMember(ctx context.Context, member *accesslist. Member: conv.ToMemberProto(member), }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } responseMember, err := conv.FromMemberProto(resp) - return responseMember, trail.FromGRPC(err) + return responseMember, trace.Wrap(err) } // DeleteAccessListMember hard deletes the specified access list member resource. @@ -172,7 +172,7 @@ func (c *Client) DeleteAccessListMember(ctx context.Context, accessList string, AccessList: accessList, MemberName: memberName, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllAccessListMembers hard deletes all access list members for an access list. @@ -180,11 +180,11 @@ func (c *Client) DeleteAllAccessListMembersForAccessList(ctx context.Context, ac _, err := c.grpcClient.DeleteAllAccessListMembersForAccessList(ctx, &accesslistv1.DeleteAllAccessListMembersForAccessListRequest{ AccessList: accessList, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllAccessListMembers hard deletes all access list members. func (c *Client) DeleteAllAccessListMembers(ctx context.Context) error { _, err := c.grpcClient.DeleteAllAccessListMembers(ctx, &accesslistv1.DeleteAllAccessListMembersRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } diff --git a/api/client/auditstreamer.go b/api/client/auditstreamer.go index 16cff88f1174..ad2d1eb73b92 100644 --- a/api/client/auditstreamer.go +++ b/api/client/auditstreamer.go @@ -21,7 +21,6 @@ import ( "sync" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "google.golang.org/grpc" ggzip "google.golang.org/grpc/encoding/gzip" @@ -35,7 +34,7 @@ func (c *Client) createOrResumeAuditStream(ctx context.Context, request proto.Au stream, err := c.grpc.CreateAuditStream(closeCtx, grpc.UseCompressor(ggzip.Name)) if err != nil { cancel() - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } s := &auditStreamer{ stream: stream, @@ -46,7 +45,7 @@ func (c *Client) createOrResumeAuditStream(ctx context.Context, request proto.Au go s.recv() err = s.stream.Send(&request) if err != nil { - return nil, trace.NewAggregate(s.Close(ctx), trail.FromGRPC(err)) + return nil, trace.NewAggregate(s.Close(ctx), trace.Wrap(err)) } return s, nil } @@ -85,7 +84,7 @@ type auditStreamer struct { // the stream completed and closes the stream instance. func (s *auditStreamer) Close(ctx context.Context) error { defer s.closeWithError(nil) - return trail.FromGRPC(s.stream.Send(&proto.AuditStreamRequest{ + return trace.Wrap(s.stream.Send(&proto.AuditStreamRequest{ Request: &proto.AuditStreamRequest_FlushAndCloseStream{ FlushAndCloseStream: &proto.FlushAndCloseStream{}, }, @@ -94,7 +93,7 @@ func (s *auditStreamer) Close(ctx context.Context) error { // Complete completes stream. func (s *auditStreamer) Complete(ctx context.Context) error { - return trail.FromGRPC(s.stream.Send(&proto.AuditStreamRequest{ + return trace.Wrap(s.stream.Send(&proto.AuditStreamRequest{ Request: &proto.AuditStreamRequest_CompleteStream{ CompleteStream: &proto.CompleteStream{}, }, @@ -113,7 +112,7 @@ func (s *auditStreamer) RecordEvent(ctx context.Context, event events.PreparedSe if err != nil { return trace.Wrap(err) } - err = trail.FromGRPC(s.stream.Send(&proto.AuditStreamRequest{ + err = trace.Wrap(s.stream.Send(&proto.AuditStreamRequest{ Request: &proto.AuditStreamRequest_Event{Event: oneof}, })) if err != nil { @@ -141,7 +140,7 @@ func (s *auditStreamer) recv() { for { status, err := s.stream.Recv() if err != nil { - s.closeWithError(trail.FromGRPC(err)) + s.closeWithError(trace.Wrap(err)) return } select { diff --git a/api/client/client.go b/api/client/client.go index 60bb27db6e53..e4bb7a45369b 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -29,7 +29,6 @@ import ( "time" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "github.com/jonboulle/clockwork" log "github.com/sirupsen/logrus" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" @@ -70,6 +69,7 @@ import ( "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/types/wrappers" "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" ) func init() { @@ -453,11 +453,13 @@ func (c *Client) dialGRPC(ctx context.Context, addr string) error { grpc.WithChainUnaryInterceptor( otelUnaryClientInterceptor(), metadata.UnaryClientInterceptor, + interceptors.GRPCClientUnaryErrorInterceptor, breaker.UnaryClientInterceptor(cb), ), grpc.WithChainStreamInterceptor( otelStreamClientInterceptor(), metadata.StreamClientInterceptor, + interceptors.GRPCClientStreamErrorInterceptor, breaker.StreamClientInterceptor(cb), ), ) @@ -674,7 +676,7 @@ func (c *Client) Dialer() ContextDialer { return c.dialer } -// GetConnection returns GRPC connection. +// GetConnection returns gRPC connection. func (c *Client) GetConnection() *grpc.ClientConn { return c.conn } @@ -719,7 +721,7 @@ func (c *Client) CreateDeviceResource(ctx context.Context, res *types.DeviceV1) CreateAsResource: true, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return types.DeviceToResource(created), nil } @@ -731,7 +733,7 @@ func (c *Client) DeleteDeviceResource(ctx context.Context, id string) error { _, err := c.DevicesClient().DeleteDevice(ctx, &devicepb.DeleteDeviceRequest{ DeviceId: id, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetDeviceResource reads a device using its ID (either devicepb.Device.Id @@ -742,7 +744,7 @@ func (c *Client) GetDeviceResource(ctx context.Context, id string) (*types.Devic DeviceId: id, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return types.DeviceToResource(dev), nil } @@ -761,7 +763,7 @@ func (c *Client) UpsertDeviceResource(ctx context.Context, res *types.DeviceV1) CreateAsResource: true, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return types.DeviceToResource(upserted), nil } @@ -800,7 +802,7 @@ func (c *Client) EmbeddingClient() assist.AssistEmbeddingServiceClient { func (c *Client) Ping(ctx context.Context) (proto.PingResponse, error) { rsp, err := c.grpc.Ping(ctx, &proto.PingRequest{}) if err != nil { - return proto.PingResponse{}, trail.FromGRPC(err) + return proto.PingResponse{}, trace.Wrap(err) } return *rsp, nil } @@ -813,7 +815,7 @@ func (c *Client) UpdateRemoteCluster(ctx context.Context, rc types.RemoteCluster } _, err := c.grpc.UpdateRemoteCluster(ctx, rcV3) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateUser creates a new user from the specified descriptor. @@ -824,7 +826,7 @@ func (c *Client) CreateUser(ctx context.Context, user types.User) error { } _, err := c.grpc.CreateUser(ctx, userV2) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpdateUser updates an existing user in a backend. @@ -835,7 +837,7 @@ func (c *Client) UpdateUser(ctx context.Context, user types.User) error { } _, err := c.grpc.UpdateUser(ctx, userV2) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetUser returns a list of usernames registered in the system. @@ -849,7 +851,7 @@ func (c *Client) GetUser(name string, withSecrets bool) (types.User, error) { WithSecrets: withSecrets, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return user, nil } @@ -859,7 +861,7 @@ func (c *Client) GetUser(name string, withSecrets bool) (types.User, error) { func (c *Client) GetCurrentUser(ctx context.Context) (types.User, error) { currentUser, err := c.grpc.GetCurrentUser(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return currentUser, nil } @@ -868,12 +870,12 @@ func (c *Client) GetCurrentUser(ctx context.Context) (types.User, error) { func (c *Client) GetCurrentUserRoles(ctx context.Context) ([]types.Role, error) { stream, err := c.grpc.GetCurrentUserRoles(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } var roles []types.Role for role, err := stream.Recv(); err != io.EOF; role, err = stream.Recv() { if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } roles = append(roles, role) } @@ -887,12 +889,12 @@ func (c *Client) GetUsers(withSecrets bool) ([]types.User, error) { WithSecrets: withSecrets, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } var users []types.User for user, err := stream.Recv(); err != io.EOF; user, err = stream.Recv() { if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } users = append(users, user) } @@ -903,7 +905,7 @@ func (c *Client) GetUsers(withSecrets bool) ([]types.User, error) { func (c *Client) DeleteUser(ctx context.Context, user string) error { req := &proto.DeleteUserRequest{Name: user} _, err := c.grpc.DeleteUser(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GenerateUserCerts takes the public key in the OpenSSH `authorized_keys` plain @@ -912,7 +914,7 @@ func (c *Client) DeleteUser(ctx context.Context, user string) error { func (c *Client) GenerateUserCerts(ctx context.Context, req proto.UserCertsRequest) (*proto.Certs, error) { certs, err := c.grpc.GenerateUserCerts(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return certs, nil } @@ -924,7 +926,7 @@ func (c *Client) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequ } certs, err := c.grpc.GenerateHostCerts(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return certs, nil } @@ -934,7 +936,7 @@ func (c *Client) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequ func (c *Client) GenerateOpenSSHCert(ctx context.Context, req *proto.OpenSSHCertRequest) (*proto.OpenSSHCert, error) { cert, err := c.grpc.GenerateOpenSSHCert(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return cert, nil } @@ -947,7 +949,7 @@ func (c *Client) EmitAuditEvent(ctx context.Context, event events.AuditEvent) er } _, err = c.grpc.EmitAuditEvent(ctx, grpcEvent) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -958,7 +960,7 @@ func (c *Client) GetResetPasswordToken(ctx context.Context, tokenID string) (typ TokenID: tokenID, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return token, nil @@ -968,7 +970,7 @@ func (c *Client) GetResetPasswordToken(ctx context.Context, tokenID string) (typ func (c *Client) CreateResetPasswordToken(ctx context.Context, req *proto.CreateResetPasswordTokenRequest) (types.UserToken, error) { token, err := c.grpc.CreateResetPasswordToken(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return token, nil @@ -978,7 +980,7 @@ func (c *Client) CreateResetPasswordToken(ctx context.Context, req *proto.Create func (c *Client) CreateBot(ctx context.Context, req *proto.CreateBotRequest) (*proto.CreateBotResponse, error) { response, err := c.grpc.CreateBot(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return response, nil @@ -989,19 +991,19 @@ func (c *Client) DeleteBot(ctx context.Context, botName string) error { _, err := c.grpc.DeleteBot(ctx, &proto.DeleteBotRequest{ Name: botName, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetBotUsers fetches all bot users. func (c *Client) GetBotUsers(ctx context.Context) ([]types.User, error) { stream, err := c.grpc.GetBotUsers(ctx, &proto.GetBotUsersRequest{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } var users []types.User for user, err := stream.Recv(); err != io.EOF; user, err = stream.Recv() { if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } users = append(users, user) } @@ -1012,7 +1014,7 @@ func (c *Client) GetBotUsers(ctx context.Context) ([]types.User, error) { func (c *Client) GetAccessRequests(ctx context.Context, filter types.AccessRequestFilter) ([]types.AccessRequest, error) { stream, err := c.grpc.GetAccessRequestsV2(ctx, &filter) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } var reqs []types.AccessRequest @@ -1023,7 +1025,7 @@ func (c *Client) GetAccessRequests(ctx context.Context, filter types.AccessReque } if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } reqs = append(reqs, req) } @@ -1038,7 +1040,7 @@ func (c *Client) CreateAccessRequest(ctx context.Context, req types.AccessReques return trace.BadParameter("unexpected access request type %T", req) } _, err := c.grpc.CreateAccessRequest(ctx, r) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateAccessRequestV2 registers a new access request with the auth server. @@ -1048,13 +1050,13 @@ func (c *Client) CreateAccessRequestV2(ctx context.Context, req types.AccessRequ return nil, trace.BadParameter("unexpected access request type %T", req) } resp, err := c.grpc.CreateAccessRequestV2(ctx, r) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // DeleteAccessRequest deletes an access request. func (c *Client) DeleteAccessRequest(ctx context.Context, reqID string) error { _, err := c.grpc.DeleteAccessRequest(ctx, &proto.RequestID{ID: reqID}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // SetAccessRequestState updates the state of an existing access request. @@ -1070,14 +1072,14 @@ func (c *Client) SetAccessRequestState(ctx context.Context, params types.AccessR setter.Delegator = d } _, err := c.grpc.SetAccessRequestState(ctx, &setter) - return trail.FromGRPC(err) + return trace.Wrap(err) } // SubmitAccessReview applies a review to a request and returns the post-application state. func (c *Client) SubmitAccessReview(ctx context.Context, params types.AccessReviewSubmission) (types.AccessRequest, error) { req, err := c.grpc.SubmitAccessReview(ctx, ¶ms) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return req, nil } @@ -1086,7 +1088,7 @@ func (c *Client) SubmitAccessReview(ctx context.Context, params types.AccessRevi func (c *Client) GetAccessCapabilities(ctx context.Context, req types.AccessCapabilitiesRequest) (*types.AccessCapabilities, error) { caps, err := c.grpc.GetAccessCapabilities(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return caps, nil } @@ -1095,7 +1097,7 @@ func (c *Client) GetAccessCapabilities(ctx context.Context, req types.AccessCapa func (c *Client) GetPluginData(ctx context.Context, filter types.PluginDataFilter) ([]types.PluginData, error) { seq, err := c.grpc.GetPluginData(ctx, &filter) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } data := make([]types.PluginData, 0, len(seq.PluginData)) for _, d := range seq.PluginData { @@ -1107,14 +1109,14 @@ func (c *Client) GetPluginData(ctx context.Context, filter types.PluginDataFilte // UpdatePluginData updates a per-resource PluginData entry. func (c *Client) UpdatePluginData(ctx context.Context, params types.PluginDataUpdateParams) error { _, err := c.grpc.UpdatePluginData(ctx, ¶ms) - return trail.FromGRPC(err) + return trace.Wrap(err) } // AcquireSemaphore acquires lease with requested resources from semaphore. func (c *Client) AcquireSemaphore(ctx context.Context, params types.AcquireSemaphoreRequest) (*types.SemaphoreLease, error) { lease, err := c.grpc.AcquireSemaphore(ctx, ¶ms) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return lease, nil } @@ -1122,20 +1124,20 @@ func (c *Client) AcquireSemaphore(ctx context.Context, params types.AcquireSemap // KeepAliveSemaphoreLease updates semaphore lease. func (c *Client) KeepAliveSemaphoreLease(ctx context.Context, lease types.SemaphoreLease) error { _, err := c.grpc.KeepAliveSemaphoreLease(ctx, &lease) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CancelSemaphoreLease cancels semaphore lease early. func (c *Client) CancelSemaphoreLease(ctx context.Context, lease types.SemaphoreLease) error { _, err := c.grpc.CancelSemaphoreLease(ctx, &lease) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetSemaphores returns a list of all semaphores matching the supplied filter. func (c *Client) GetSemaphores(ctx context.Context, filter types.SemaphoreFilter) ([]types.Semaphore, error) { rsp, err := c.grpc.GetSemaphores(ctx, &filter) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } sems := make([]types.Semaphore, 0, len(rsp.Semaphores)) for _, s := range rsp.Semaphores { @@ -1147,7 +1149,7 @@ func (c *Client) GetSemaphores(ctx context.Context, filter types.SemaphoreFilter // DeleteSemaphore deletes a semaphore matching the supplied filter. func (c *Client) DeleteSemaphore(ctx context.Context, filter types.SemaphoreFilter) error { _, err := c.grpc.DeleteSemaphore(ctx, &filter) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetKubernetesServers returns the list of kubernetes servers registered in the @@ -1166,13 +1168,13 @@ func (c *Client) DeleteKubernetesServer(ctx context.Context, hostID, name string HostID: hostID, Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllKubernetesServers deletes all registered kubernetes servers. func (c *Client) DeleteAllKubernetesServers(ctx context.Context) error { _, err := c.grpc.DeleteAllKubernetesServers(ctx, &proto.DeleteAllKubernetesServersRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpsertKubernetesServer is used by kubernetes services to report their presence @@ -1184,7 +1186,7 @@ func (c *Client) UpsertKubernetesServer(ctx context.Context, s types.KubeServer) } keepAlive, err := c.grpc.UpsertKubernetesServer(ctx, &proto.UpsertKubernetesServerRequest{Server: server}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return keepAlive, nil } @@ -1195,7 +1197,7 @@ func (c *Client) GetApplicationServers(ctx context.Context, namespace string) ([ Namespace: namespace, ResourceType: types.KindAppServer, }) - return servers, trail.FromGRPC(err) + return servers, trace.Wrap(err) } // UpsertApplicationServer registers an application server. @@ -1208,7 +1210,7 @@ func (c *Client) UpsertApplicationServer(ctx context.Context, server types.AppSe Server: s, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return keepAlive, nil } @@ -1220,7 +1222,7 @@ func (c *Client) DeleteApplicationServer(ctx context.Context, namespace, hostID, HostID: hostID, Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllApplicationServers removes all registered application servers. @@ -1228,7 +1230,7 @@ func (c *Client) DeleteAllApplicationServers(ctx context.Context, namespace stri _, err := c.grpc.DeleteAllApplicationServers(ctx, &proto.DeleteAllApplicationServersRequest{ Namespace: namespace, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetAppSession gets an application web session. @@ -1237,7 +1239,7 @@ func (c *Client) GetAppSession(ctx context.Context, req types.GetAppSessionReque SessionID: req.SessionID, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.GetSession(), nil @@ -1253,7 +1255,7 @@ func (c *Client) ListAppSessions(ctx context.Context, pageSize int, pageToken, u User: user, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } out := make([]types.WebSession, 0, len(resp.GetSessions())) @@ -1267,7 +1269,7 @@ func (c *Client) ListAppSessions(ctx context.Context, pageSize int, pageToken, u func (c *Client) GetSnowflakeSessions(ctx context.Context) ([]types.WebSession, error) { resp, err := c.grpc.GetSnowflakeSessions(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } out := make([]types.WebSession, 0, len(resp.GetSessions())) @@ -1287,7 +1289,7 @@ func (c *Client) ListSAMLIdPSessions(ctx context.Context, pageSize int, pageToke User: user, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } out := make([]types.WebSession, 0, len(resp.GetSessions())) @@ -1309,7 +1311,7 @@ func (c *Client) CreateAppSession(ctx context.Context, req types.CreateAppSessio GCPServiceAccount: req.GCPServiceAccount, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.GetSession(), nil @@ -1323,7 +1325,7 @@ func (c *Client) CreateSnowflakeSession(ctx context.Context, req types.CreateSno TokenTTL: proto.Duration(req.TokenTTL), }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.GetSession(), nil @@ -1337,7 +1339,7 @@ func (c *Client) CreateSAMLIdPSession(ctx context.Context, req types.CreateSAMLI SAMLSession: req.SAMLSession, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.GetSession(), nil @@ -1349,7 +1351,7 @@ func (c *Client) GetSnowflakeSession(ctx context.Context, req types.GetSnowflake SessionID: req.SessionID, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.GetSession(), nil @@ -1361,7 +1363,7 @@ func (c *Client) GetSAMLIdPSession(ctx context.Context, req types.GetSAMLIdPSess SessionID: req.SessionID, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.GetSession(), nil @@ -1372,7 +1374,7 @@ func (c *Client) DeleteAppSession(ctx context.Context, req types.DeleteAppSessio _, err := c.grpc.DeleteAppSession(ctx, &proto.DeleteAppSessionRequest{ SessionID: req.SessionID, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteSnowflakeSession removes a Snowflake web session. @@ -1380,7 +1382,7 @@ func (c *Client) DeleteSnowflakeSession(ctx context.Context, req types.DeleteSno _, err := c.grpc.DeleteSnowflakeSession(ctx, &proto.DeleteSnowflakeSessionRequest{ SessionID: req.SessionID, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteSAMLIdPSession removes a SAML IdP session. @@ -1388,31 +1390,31 @@ func (c *Client) DeleteSAMLIdPSession(ctx context.Context, req types.DeleteSAMLI _, err := c.grpc.DeleteSAMLIdPSession(ctx, &proto.DeleteSAMLIdPSessionRequest{ SessionID: req.SessionID, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllAppSessions removes all application web sessions. func (c *Client) DeleteAllAppSessions(ctx context.Context) error { _, err := c.grpc.DeleteAllAppSessions(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllSnowflakeSessions removes all Snowflake web sessions. func (c *Client) DeleteAllSnowflakeSessions(ctx context.Context) error { _, err := c.grpc.DeleteAllSnowflakeSessions(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllSAMLIdPSessions removes all SAML IdP sessions. func (c *Client) DeleteAllSAMLIdPSessions(ctx context.Context) error { _, err := c.grpc.DeleteAllSAMLIdPSessions(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteUserAppSessions deletes all user’s application sessions. func (c *Client) DeleteUserAppSessions(ctx context.Context, req *proto.DeleteUserAppSessionsRequest) error { _, err := c.grpc.DeleteUserAppSessions(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteUserSAMLIdPSessions deletes all user’s SAML IdP sessions. @@ -1421,7 +1423,7 @@ func (c *Client) DeleteUserSAMLIdPSessions(ctx context.Context, username string) Username: username, } _, err := c.grpc.DeleteUserSAMLIdPSessions(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GenerateAppToken creates a JWT token with application access. @@ -1440,7 +1442,7 @@ func (c *Client) GenerateAppToken(ctx context.Context, req types.GenerateAppToke Expires: req.Expires, }) if err != nil { - return "", trail.FromGRPC(err) + return "", trace.Wrap(err) } return resp.GetToken(), nil @@ -1453,7 +1455,7 @@ func (c *Client) GenerateSnowflakeJWT(ctx context.Context, req types.GenerateSno AccountName: req.Account, }) if err != nil { - return "", trail.FromGRPC(err) + return "", trace.Wrap(err) } return resp.GetToken(), nil @@ -1469,7 +1471,7 @@ func (c *Client) GetDatabaseServers(ctx context.Context, namespace string) ([]ty Namespace: namespace, ResourceType: types.KindDatabaseServer, }) - return servers, trail.FromGRPC(err) + return servers, trace.Wrap(err) } // UpsertDatabaseServer registers a new database proxy server. @@ -1482,7 +1484,7 @@ func (c *Client) UpsertDatabaseServer(ctx context.Context, server types.Database Server: s, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return keepAlive, nil } @@ -1495,7 +1497,7 @@ func (c *Client) DeleteDatabaseServer(ctx context.Context, namespace, hostID, na Name: name, }) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -1506,7 +1508,7 @@ func (c *Client) DeleteAllDatabaseServers(ctx context.Context, namespace string) Namespace: namespace, }) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -1516,7 +1518,7 @@ func (c *Client) DeleteAllDatabaseServers(ctx context.Context, namespace string) func (c *Client) SignDatabaseCSR(ctx context.Context, req *proto.DatabaseCSRRequest) (*proto.DatabaseCSRResponse, error) { resp, err := c.grpc.SignDatabaseCSR(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1526,7 +1528,7 @@ func (c *Client) SignDatabaseCSR(ctx context.Context, req *proto.DatabaseCSRRequ func (c *Client) GenerateDatabaseCert(ctx context.Context, req *proto.DatabaseCertRequest) (*proto.DatabaseCertResponse, error) { resp, err := c.grpc.GenerateDatabaseCert(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1538,7 +1540,7 @@ func (c *Client) GetRole(ctx context.Context, name string) (types.Role, error) { } role, err := c.grpc.GetRole(ctx, &proto.GetRoleRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return role, nil } @@ -1547,7 +1549,7 @@ func (c *Client) GetRole(ctx context.Context, name string) (types.Role, error) { func (c *Client) GetRoles(ctx context.Context) ([]types.Role, error) { resp, err := c.grpc.GetRoles(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } roles := make([]types.Role, 0, len(resp.GetRoles())) for _, role := range resp.GetRoles() { @@ -1564,7 +1566,7 @@ func (c *Client) UpsertRole(ctx context.Context, role types.Role) error { } _, err := c.grpc.UpsertRole(ctx, r) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteRole deletes role by name @@ -1573,13 +1575,13 @@ func (c *Client) DeleteRole(ctx context.Context, name string) error { return trace.BadParameter("missing name") } _, err := c.grpc.DeleteRole(ctx, &proto.DeleteRoleRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } func (c *Client) AddMFADevice(ctx context.Context) (proto.AuthService_AddMFADeviceClient, error) { stream, err := c.grpc.AddMFADevice(ctx) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return stream, nil } @@ -1587,7 +1589,7 @@ func (c *Client) AddMFADevice(ctx context.Context) (proto.AuthService_AddMFADevi func (c *Client) DeleteMFADevice(ctx context.Context) (proto.AuthService_DeleteMFADeviceClient, error) { stream, err := c.grpc.DeleteMFADevice(ctx) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return stream, nil } @@ -1595,19 +1597,19 @@ func (c *Client) DeleteMFADevice(ctx context.Context) (proto.AuthService_DeleteM // AddMFADeviceSync adds a new MFA device (nonstream). func (c *Client) AddMFADeviceSync(ctx context.Context, in *proto.AddMFADeviceSyncRequest) (*proto.AddMFADeviceSyncResponse, error) { res, err := c.grpc.AddMFADeviceSync(ctx, in) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // DeleteMFADeviceSync deletes a users MFA device (nonstream). func (c *Client) DeleteMFADeviceSync(ctx context.Context, in *proto.DeleteMFADeviceSyncRequest) error { _, err := c.grpc.DeleteMFADeviceSync(ctx, in) - return trail.FromGRPC(err) + return trace.Wrap(err) } func (c *Client) GetMFADevices(ctx context.Context, in *proto.GetMFADevicesRequest) (*proto.GetMFADevicesResponse, error) { resp, err := c.grpc.GetMFADevices(ctx, in) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1615,7 +1617,7 @@ func (c *Client) GetMFADevices(ctx context.Context, in *proto.GetMFADevicesReque func (c *Client) GenerateUserSingleUseCerts(ctx context.Context) (proto.AuthService_GenerateUserSingleUseCertsClient, error) { stream, err := c.grpc.GenerateUserSingleUseCerts(ctx) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return stream, nil } @@ -1623,7 +1625,7 @@ func (c *Client) GenerateUserSingleUseCerts(ctx context.Context) (proto.AuthServ func (c *Client) IsMFARequired(ctx context.Context, req *proto.IsMFARequiredRequest) (*proto.IsMFARequiredResponse, error) { resp, err := c.grpc.IsMFARequired(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1636,7 +1638,7 @@ func (c *Client) GetOIDCConnector(ctx context.Context, name string, withSecrets req := &types.ResourceWithSecretsRequest{Name: name, WithSecrets: withSecrets} resp, err := c.grpc.GetOIDCConnector(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1646,7 +1648,7 @@ func (c *Client) GetOIDCConnectors(ctx context.Context, withSecrets bool) ([]typ req := &types.ResourcesWithSecretsRequest{WithSecrets: withSecrets} resp, err := c.grpc.GetOIDCConnectors(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } oidcConnectors := make([]types.OIDCConnector, len(resp.OIDCConnectors)) for i, oidcConnector := range resp.OIDCConnectors { @@ -1662,7 +1664,7 @@ func (c *Client) UpsertOIDCConnector(ctx context.Context, oidcConnector types.OI return trace.BadParameter("invalid type %T", oidcConnector) } _, err := c.grpc.UpsertOIDCConnector(ctx, connector) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteOIDCConnector deletes an OIDC connector by name. @@ -1671,14 +1673,14 @@ func (c *Client) DeleteOIDCConnector(ctx context.Context, name string) error { return trace.BadParameter("cannot delete OIDC Connector, missing name") } _, err := c.grpc.DeleteOIDCConnector(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateOIDCAuthRequest creates OIDCAuthRequest. func (c *Client) CreateOIDCAuthRequest(ctx context.Context, req types.OIDCAuthRequest) (*types.OIDCAuthRequest, error) { resp, err := c.grpc.CreateOIDCAuthRequest(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1688,7 +1690,7 @@ func (c *Client) GetOIDCAuthRequest(ctx context.Context, stateToken string) (*ty req := &proto.GetOIDCAuthRequestRequest{StateToken: stateToken} resp, err := c.grpc.GetOIDCAuthRequest(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1701,7 +1703,7 @@ func (c *Client) GetSAMLConnector(ctx context.Context, name string, withSecrets req := &types.ResourceWithSecretsRequest{Name: name, WithSecrets: withSecrets} resp, err := c.grpc.GetSAMLConnector(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1711,7 +1713,7 @@ func (c *Client) GetSAMLConnectors(ctx context.Context, withSecrets bool) ([]typ req := &types.ResourcesWithSecretsRequest{WithSecrets: withSecrets} resp, err := c.grpc.GetSAMLConnectors(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } samlConnectors := make([]types.SAMLConnector, len(resp.SAMLConnectors)) for i, samlConnector := range resp.SAMLConnectors { @@ -1727,7 +1729,7 @@ func (c *Client) UpsertSAMLConnector(ctx context.Context, connector types.SAMLCo return trace.BadParameter("invalid type %T", connector) } _, err := c.grpc.UpsertSAMLConnector(ctx, samlConnectorV2) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteSAMLConnector deletes a SAML connector by name. @@ -1736,14 +1738,14 @@ func (c *Client) DeleteSAMLConnector(ctx context.Context, name string) error { return trace.BadParameter("cannot delete SAML Connector, missing name") } _, err := c.grpc.DeleteSAMLConnector(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateSAMLAuthRequest creates SAMLAuthRequest. func (c *Client) CreateSAMLAuthRequest(ctx context.Context, req types.SAMLAuthRequest) (*types.SAMLAuthRequest, error) { resp, err := c.grpc.CreateSAMLAuthRequest(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1753,7 +1755,7 @@ func (c *Client) GetSAMLAuthRequest(ctx context.Context, id string) (*types.SAML req := &proto.GetSAMLAuthRequestRequest{ID: id} resp, err := c.grpc.GetSAMLAuthRequest(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1766,7 +1768,7 @@ func (c *Client) GetGithubConnector(ctx context.Context, name string, withSecret req := &types.ResourceWithSecretsRequest{Name: name, WithSecrets: withSecrets} resp, err := c.grpc.GetGithubConnector(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1776,7 +1778,7 @@ func (c *Client) GetGithubConnectors(ctx context.Context, withSecrets bool) ([]t req := &types.ResourcesWithSecretsRequest{WithSecrets: withSecrets} resp, err := c.grpc.GetGithubConnectors(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } githubConnectors := make([]types.GithubConnector, len(resp.GithubConnectors)) for i, githubConnector := range resp.GithubConnectors { @@ -1792,7 +1794,7 @@ func (c *Client) UpsertGithubConnector(ctx context.Context, connector types.Gith return trace.BadParameter("invalid type %T", connector) } _, err := c.grpc.UpsertGithubConnector(ctx, githubConnector) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteGithubConnector deletes a Github connector by name. @@ -1801,14 +1803,14 @@ func (c *Client) DeleteGithubConnector(ctx context.Context, name string) error { return trace.BadParameter("cannot delete GitHub Connector, missing name") } _, err := c.grpc.DeleteGithubConnector(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateGithubAuthRequest creates GithubAuthRequest. func (c *Client) CreateGithubAuthRequest(ctx context.Context, req types.GithubAuthRequest) (*types.GithubAuthRequest, error) { resp, err := c.grpc.CreateGithubAuthRequest(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1818,7 +1820,7 @@ func (c *Client) GetGithubAuthRequest(ctx context.Context, stateToken string) (* req := &proto.GetGithubAuthRequestRequest{StateToken: stateToken} resp, err := c.grpc.GetGithubAuthRequest(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1828,7 +1830,7 @@ func (c *Client) GetSSODiagnosticInfo(ctx context.Context, authRequestKind strin req := &proto.GetSSODiagnosticInfoRequest{AuthRequestKind: authRequestKind, AuthRequestID: authRequestID} resp, err := c.grpc.GetSSODiagnosticInfo(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1842,7 +1844,7 @@ func (c *Client) GetServerInfos(ctx context.Context) stream.Stream[types.ServerI serverInfos, err := c.grpc.GetServerInfos(ctx, &emptypb.Empty{}) if err != nil { cancel() - return stream.Fail[types.ServerInfo](trail.FromGRPC(err)) + return stream.Fail[types.ServerInfo](trace.Wrap(err)) } return stream.Func(func() (types.ServerInfo, error) { si, err := serverInfos.Recv() @@ -1851,7 +1853,7 @@ func (c *Client) GetServerInfos(ctx context.Context) stream.Stream[types.ServerI // io.EOF signals that stream has completed successfully return nil, io.EOF } - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return si, nil }, cancel) @@ -1865,7 +1867,7 @@ func (c *Client) GetServerInfo(ctx context.Context, name string) (types.ServerIn req := &types.ResourceRequest{Name: name} resp, err := c.grpc.GetServerInfo(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1877,7 +1879,7 @@ func (c *Client) UpsertServerInfo(ctx context.Context, serverInfo types.ServerIn return trace.BadParameter("invalid type %T", serverInfo) } _, err := c.grpc.UpsertServerInfo(ctx, si) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteServerInfo deletes a ServerInfo by name. @@ -1887,13 +1889,13 @@ func (c *Client) DeleteServerInfo(ctx context.Context, name string) error { } req := &types.ResourceRequest{Name: name} _, err := c.grpc.DeleteServerInfo(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllServerInfos deletes all ServerInfos. func (c *Client) DeleteAllServerInfos(ctx context.Context) error { _, err := c.grpc.DeleteAllServerInfos(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetTrustedCluster returns a Trusted Cluster by name. @@ -1904,7 +1906,7 @@ func (c *Client) GetTrustedCluster(ctx context.Context, name string) (types.Trus req := &types.ResourceRequest{Name: name} resp, err := c.grpc.GetTrustedCluster(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1913,7 +1915,7 @@ func (c *Client) GetTrustedCluster(ctx context.Context, name string) (types.Trus func (c *Client) GetTrustedClusters(ctx context.Context) ([]types.TrustedCluster, error) { resp, err := c.grpc.GetTrustedClusters(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } trustedClusters := make([]types.TrustedCluster, len(resp.TrustedClusters)) for i, trustedCluster := range resp.TrustedClusters { @@ -1930,7 +1932,7 @@ func (c *Client) UpsertTrustedCluster(ctx context.Context, trusedCluster types.T } resp, err := c.grpc.UpsertTrustedCluster(ctx, trustedCluster) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1941,7 +1943,7 @@ func (c *Client) DeleteTrustedCluster(ctx context.Context, name string) error { return trace.BadParameter("cannot delete trusted cluster, missing name") } _, err := c.grpc.DeleteTrustedCluster(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetToken returns a provision token by name. @@ -1951,7 +1953,7 @@ func (c *Client) GetToken(ctx context.Context, name string) (types.ProvisionToke } resp, err := c.grpc.GetToken(ctx, &types.ResourceRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -1960,7 +1962,7 @@ func (c *Client) GetToken(ctx context.Context, name string) (types.ProvisionToke func (c *Client) GetTokens(ctx context.Context) ([]types.ProvisionToken, error) { resp, err := c.grpc.GetTokens(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } tokens := make([]types.ProvisionToken, len(resp.ProvisionTokens)) @@ -1982,7 +1984,7 @@ func (c *Client) UpsertToken(ctx context.Context, token types.ProvisionToken) er V2: tokenV2, }, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateToken creates a provision token. @@ -1997,7 +1999,7 @@ func (c *Client) CreateToken(ctx context.Context, token types.ProvisionToken) er V2: tokenV2, }, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteToken deletes a provision token by name. @@ -2006,7 +2008,7 @@ func (c *Client) DeleteToken(ctx context.Context, name string) error { return trace.BadParameter("cannot delete token, missing name") } _, err := c.grpc.DeleteToken(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetNode returns a node by name and namespace. @@ -2016,7 +2018,7 @@ func (c *Client) GetNode(ctx context.Context, namespace, name string) (types.Ser Namespace: namespace, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -2043,7 +2045,7 @@ func (c *Client) UpsertNode(ctx context.Context, node types.Server) (*types.Keep } keepAlive, err := c.grpc.UpsertNode(ctx, serverV2) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return keepAlive, nil } @@ -2060,7 +2062,7 @@ func (c *Client) DeleteNode(ctx context.Context, namespace, name string) error { Name: name, Namespace: namespace, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllNodes deletes all nodes in a given namespace. @@ -2069,7 +2071,7 @@ func (c *Client) DeleteAllNodes(ctx context.Context, namespace string) error { return trace.BadParameter("missing parameter namespace") } _, err := c.grpc.DeleteAllNodes(ctx, &types.ResourcesInNamespaceRequest{Namespace: namespace}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // StreamSessionEvents streams audit events from a given session recording. @@ -2094,7 +2096,7 @@ func (c *Client) StreamSessionEvents(ctx context.Context, sessionID string, star oneOf, err := stream.Recv() if err != nil { if err != io.EOF { - e <- trace.Wrap(trail.FromGRPC(err)) + e <- trace.Wrap(trace.Wrap(err)) } else { close(ch) } @@ -2104,7 +2106,7 @@ func (c *Client) StreamSessionEvents(ctx context.Context, sessionID string, star event, err := events.FromOneOf(*oneOf) if err != nil { - e <- trace.Wrap(trail.FromGRPC(err)) + e <- trace.Wrap(trace.Wrap(err)) break outer } @@ -2134,7 +2136,7 @@ func (c *Client) SearchEvents(ctx context.Context, fromUTC, toUTC time.Time, nam response, err := c.grpc.GetEvents(ctx, request) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } decodedEvents := make([]events.AuditEvent, 0, len(response.Items)) @@ -2170,7 +2172,7 @@ func (c *Client) SearchUnstructuredEvents(ctx context.Context, fromUTC, toUTC ti response, err := c.grpc.GetUnstructuredEvents(ctx, request) if err != nil { - err = trail.FromGRPC(err) + err = trace.Wrap(err) // If the server does not support the unstructured events API, // fallback to the legacy API. if trace.IsNotImplemented(err) { @@ -2220,7 +2222,7 @@ func (c *Client) StreamUnstructuredSessionEvents(ctx context.Context, sessionID stream, err := c.grpc.StreamUnstructuredSessionEvents(ctx, request) if err != nil { - if trace.IsNotImplemented(trail.FromGRPC(err)) { + if trace.IsNotImplemented(trace.Wrap(err)) { // If the server does not support the unstructured events API, // fallback to the legacy API. // This code patch shouldn't be triggered because the server @@ -2229,7 +2231,7 @@ func (c *Client) StreamUnstructuredSessionEvents(ctx context.Context, sessionID // on the client grpc side. c.streamUnstructuredSessionEventsFallback(ctx, sessionID, startIndex, ch, e) } else { - e <- trace.Wrap(trail.FromGRPC(err)) + e <- trace.Wrap(trace.Wrap(err)) } return ch, e } @@ -2246,13 +2248,13 @@ func (c *Client) StreamUnstructuredSessionEvents(ctx context.Context, sessionID // unstructured format and sends them to the channel ch. // Once we decide to spin the goroutine, we can leave this loop without // reporting any error to the caller. - if trace.IsNotImplemented(trail.FromGRPC(err)) { + if trace.IsNotImplemented(trace.Wrap(err)) { // If the server does not support the unstructured events API, // fallback to the legacy API. go c.streamUnstructuredSessionEventsFallback(ctx, sessionID, startIndex, ch, e) return } - e <- trace.Wrap(trail.FromGRPC(err)) + e <- trace.Wrap(trace.Wrap(err)) } else { close(ch) } @@ -2296,7 +2298,7 @@ func (c *Client) streamUnstructuredSessionEventsFallback(ctx context.Context, se oneOf, err := stream.Recv() if err != nil { if err != io.EOF { - e <- trace.Wrap(trail.FromGRPC(err)) + e <- trace.Wrap(trace.Wrap(err)) } else { close(ch) } @@ -2306,7 +2308,7 @@ func (c *Client) streamUnstructuredSessionEventsFallback(ctx context.Context, se event, err := events.FromOneOf(*oneOf) if err != nil { - e <- trace.Wrap(trail.FromGRPC(err)) + e <- trace.Wrap(trace.Wrap(err)) return } @@ -2338,7 +2340,7 @@ func (c *Client) SearchSessionEvents(ctx context.Context, fromUTC time.Time, toU response, err := c.grpc.GetSessionEvents(ctx, request) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } decodedEvents := make([]events.AuditEvent, 0, len(response.Items)) @@ -2357,7 +2359,7 @@ func (c *Client) SearchSessionEvents(ctx context.Context, fromUTC time.Time, toU func (c *Client) GetClusterNetworkingConfig(ctx context.Context) (types.ClusterNetworkingConfig, error) { resp, err := c.grpc.GetClusterNetworkingConfig(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -2369,20 +2371,20 @@ func (c *Client) SetClusterNetworkingConfig(ctx context.Context, netConfig types return trace.BadParameter("invalid type %T", netConfig) } _, err := c.grpc.SetClusterNetworkingConfig(ctx, netConfigV2) - return trail.FromGRPC(err) + return trace.Wrap(err) } // ResetClusterNetworkingConfig resets cluster networking configuration to defaults. func (c *Client) ResetClusterNetworkingConfig(ctx context.Context) error { _, err := c.grpc.ResetClusterNetworkingConfig(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetSessionRecordingConfig gets session recording configuration. func (c *Client) GetSessionRecordingConfig(ctx context.Context) (types.SessionRecordingConfig, error) { resp, err := c.grpc.GetSessionRecordingConfig(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -2394,20 +2396,20 @@ func (c *Client) SetSessionRecordingConfig(ctx context.Context, recConfig types. return trace.BadParameter("invalid type %T", recConfig) } _, err := c.grpc.SetSessionRecordingConfig(ctx, recConfigV2) - return trail.FromGRPC(err) + return trace.Wrap(err) } // ResetSessionRecordingConfig resets session recording configuration to defaults. func (c *Client) ResetSessionRecordingConfig(ctx context.Context) error { _, err := c.grpc.ResetSessionRecordingConfig(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetAuthPreference gets cluster auth preference. func (c *Client) GetAuthPreference(ctx context.Context) (types.AuthPreference, error) { pref, err := c.grpc.GetAuthPreference(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return pref, nil } @@ -2419,20 +2421,20 @@ func (c *Client) SetAuthPreference(ctx context.Context, authPref types.AuthPrefe return trace.BadParameter("invalid type %T", authPref) } _, err := c.grpc.SetAuthPreference(ctx, authPrefV2) - return trail.FromGRPC(err) + return trace.Wrap(err) } // ResetAuthPreference resets cluster auth preference to defaults. func (c *Client) ResetAuthPreference(ctx context.Context) error { _, err := c.grpc.ResetAuthPreference(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetClusterAuditConfig gets cluster audit configuration. func (c *Client) GetClusterAuditConfig(ctx context.Context) (types.ClusterAuditConfig, error) { resp, err := c.grpc.GetClusterAuditConfig(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -2441,7 +2443,7 @@ func (c *Client) GetClusterAuditConfig(ctx context.Context) (types.ClusterAuditC func (c *Client) GetInstallers(ctx context.Context) ([]types.Installer, error) { resp, err := c.grpc.GetInstallers(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } installers := make([]types.Installer, len(resp.Installers)) for i, inst := range resp.Installers { @@ -2453,7 +2455,7 @@ func (c *Client) GetInstallers(ctx context.Context) ([]types.Installer, error) { // GetUIConfig gets the configuration for the UI served by the proxy service func (c *Client) GetUIConfig(ctx context.Context) (types.UIConfig, error) { resp, err := c.grpc.GetUIConfig(ctx, &emptypb.Empty{}) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // SetUIConfig sets the configuration for the UI served by the proxy service @@ -2463,19 +2465,19 @@ func (c *Client) SetUIConfig(ctx context.Context, uic types.UIConfig) error { return trace.BadParameter("invalid type %T", uic) } _, err := c.grpc.SetUIConfig(ctx, uicV1) - return trail.FromGRPC(err) + return trace.Wrap(err) } func (c *Client) DeleteUIConfig(ctx context.Context) error { _, err := c.grpc.DeleteUIConfig(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetInstaller gets the cluster installer resource func (c *Client) GetInstaller(ctx context.Context, name string) (types.Installer, error) { resp, err := c.grpc.GetInstaller(ctx, &types.ResourceRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -2487,19 +2489,19 @@ func (c *Client) SetInstaller(ctx context.Context, inst types.Installer) error { return trace.BadParameter("invalid type %T", inst) } _, err := c.grpc.SetInstaller(ctx, instV1) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteInstaller deletes the cluster installer resource func (c *Client) DeleteInstaller(ctx context.Context, name string) error { _, err := c.grpc.DeleteInstaller(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllInstallers deletes all the installer resources. func (c *Client) DeleteAllInstallers(ctx context.Context) error { _, err := c.grpc.DeleteAllInstallers(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetLock gets a lock by name. @@ -2509,7 +2511,7 @@ func (c *Client) GetLock(ctx context.Context, name string) (types.Lock, error) { } resp, err := c.grpc.GetLock(ctx, &proto.GetLockRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -2525,7 +2527,7 @@ func (c *Client) GetLocks(ctx context.Context, inForceOnly bool, targets ...type Targets: targetPtrs, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } locks := make([]types.Lock, 0, len(resp.Locks)) for _, lock := range resp.Locks { @@ -2541,7 +2543,7 @@ func (c *Client) UpsertLock(ctx context.Context, lock types.Lock) error { return trace.BadParameter("invalid type %T", lock) } _, err := c.grpc.UpsertLock(ctx, lockV2) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteLock deletes a lock. @@ -2550,7 +2552,7 @@ func (c *Client) DeleteLock(ctx context.Context, name string) error { return trace.BadParameter("missing lock name") } _, err := c.grpc.DeleteLock(ctx, &proto.DeleteLockRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // ReplaceRemoteLocks replaces the set of locks associated with a remote cluster. @@ -2570,14 +2572,14 @@ func (c *Client) ReplaceRemoteLocks(ctx context.Context, clusterName string, loc ClusterName: clusterName, Locks: lockV2s, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetNetworkRestrictions retrieves the network restrictions func (c *Client) GetNetworkRestrictions(ctx context.Context) (types.NetworkRestrictions, error) { nr, err := c.grpc.GetNetworkRestrictions(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return nr, nil } @@ -2590,7 +2592,7 @@ func (c *Client) SetNetworkRestrictions(ctx context.Context, nr types.NetworkRes } _, err := c.grpc.SetNetworkRestrictions(ctx, restrictionsV4) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -2599,7 +2601,7 @@ func (c *Client) SetNetworkRestrictions(ctx context.Context, nr types.NetworkRes func (c *Client) DeleteNetworkRestrictions(ctx context.Context) error { _, err := c.grpc.DeleteNetworkRestrictions(ctx, &emptypb.Empty{}) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -2611,7 +2613,7 @@ func (c *Client) CreateApp(ctx context.Context, app types.Application) error { return trace.BadParameter("unsupported application type %T", app) } _, err := c.grpc.CreateApp(ctx, appV3) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpdateApp updates existing application resource. @@ -2621,7 +2623,7 @@ func (c *Client) UpdateApp(ctx context.Context, app types.Application) error { return trace.BadParameter("unsupported application type %T", app) } _, err := c.grpc.UpdateApp(ctx, appV3) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetApp returns the specified application resource. @@ -2639,7 +2641,7 @@ func (c *Client) GetApp(ctx context.Context, name string) (types.Application, er } app, err := c.grpc.GetApp(ctx, &types.ResourceRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return app, nil } @@ -2656,7 +2658,7 @@ func (c *Client) GetApp(ctx context.Context, name string) (types.Application, er func (c *Client) GetApps(ctx context.Context) ([]types.Application, error) { items, err := c.grpc.GetApps(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } apps := make([]types.Application, len(items.Apps)) for i := range items.Apps { @@ -2668,13 +2670,13 @@ func (c *Client) GetApps(ctx context.Context) ([]types.Application, error) { // DeleteApp deletes specified application resource. func (c *Client) DeleteApp(ctx context.Context, name string) error { _, err := c.grpc.DeleteApp(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllApps deletes all application resources. func (c *Client) DeleteAllApps(ctx context.Context) error { _, err := c.grpc.DeleteAllApps(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateKubernetesCluster creates a new kubernetes cluster resource. @@ -2684,7 +2686,7 @@ func (c *Client) CreateKubernetesCluster(ctx context.Context, cluster types.Kube return trace.BadParameter("unsupported kubernetes cluster type %T", cluster) } _, err := c.grpc.CreateKubernetesCluster(ctx, kubeClusterV3) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpdateKubernetesCluster updates existing kubernetes cluster resource. @@ -2694,7 +2696,7 @@ func (c *Client) UpdateKubernetesCluster(ctx context.Context, cluster types.Kube return trace.BadParameter("unsupported kubernetes cluster type %T", cluster) } _, err := c.grpc.UpdateKubernetesCluster(ctx, kubeClusterV3) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetKubernetesCluster returns the specified kubernetes resource. @@ -2704,7 +2706,7 @@ func (c *Client) GetKubernetesCluster(ctx context.Context, name string) (types.K } cluster, err := c.grpc.GetKubernetesCluster(ctx, &types.ResourceRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return cluster, nil } @@ -2713,7 +2715,7 @@ func (c *Client) GetKubernetesCluster(ctx context.Context, name string) (types.K func (c *Client) GetKubernetesClusters(ctx context.Context) ([]types.KubeCluster, error) { items, err := c.grpc.GetKubernetesClusters(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } clusters := make([]types.KubeCluster, len(items.KubernetesClusters)) for i := range items.KubernetesClusters { @@ -2725,13 +2727,13 @@ func (c *Client) GetKubernetesClusters(ctx context.Context) ([]types.KubeCluster // DeleteKubernetesCluster deletes specified kubernetes cluster resource. func (c *Client) DeleteKubernetesCluster(ctx context.Context, name string) error { _, err := c.grpc.DeleteKubernetesCluster(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllKubernetesClusters deletes all kubernetes cluster resources. func (c *Client) DeleteAllKubernetesClusters(ctx context.Context) error { _, err := c.grpc.DeleteAllKubernetesClusters(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateDatabase creates a new database resource. @@ -2741,7 +2743,7 @@ func (c *Client) CreateDatabase(ctx context.Context, database types.Database) er return trace.BadParameter("unsupported database type %T", database) } _, err := c.grpc.CreateDatabase(ctx, databaseV3) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpdateDatabase updates existing database resource. @@ -2751,7 +2753,7 @@ func (c *Client) UpdateDatabase(ctx context.Context, database types.Database) er return trace.BadParameter("unsupported database type %T", database) } _, err := c.grpc.UpdateDatabase(ctx, databaseV3) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetDatabase returns the specified database resource. @@ -2771,7 +2773,7 @@ func (c *Client) GetDatabase(ctx context.Context, name string) (types.Database, } database, err := c.grpc.GetDatabase(ctx, &types.ResourceRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return database, nil } @@ -2790,7 +2792,7 @@ func (c *Client) GetDatabase(ctx context.Context, name string) (types.Database, func (c *Client) GetDatabases(ctx context.Context) ([]types.Database, error) { items, err := c.grpc.GetDatabases(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } databases := make([]types.Database, len(items.Databases)) for i := range items.Databases { @@ -2802,13 +2804,13 @@ func (c *Client) GetDatabases(ctx context.Context) ([]types.Database, error) { // DeleteDatabase deletes specified database resource. func (c *Client) DeleteDatabase(ctx context.Context, name string) error { _, err := c.grpc.DeleteDatabase(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllDatabases deletes all database resources. func (c *Client) DeleteAllDatabases(ctx context.Context) error { _, err := c.grpc.DeleteAllDatabases(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpsertDatabaseService creates or updates existing DatabaseService resource. @@ -2821,27 +2823,27 @@ func (c *Client) UpsertDatabaseService(ctx context.Context, service types.Databa Service: serviceV1, }) - return keepAlive, trail.FromGRPC(err) + return keepAlive, trace.Wrap(err) } // DeleteDatabaseService deletes a specific DatabaseService resource. func (c *Client) DeleteDatabaseService(ctx context.Context, name string) error { _, err := c.grpc.DeleteDatabaseService(ctx, &types.ResourceRequest{Name: name}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllDatabaseServices deletes all DatabaseService resources. // If an error occurs, a partial delete may happen. func (c *Client) DeleteAllDatabaseServices(ctx context.Context) error { _, err := c.grpc.DeleteAllDatabaseServices(ctx, &proto.DeleteAllDatabaseServicesRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetWindowsDesktopServices returns all registered windows desktop services. func (c *Client) GetWindowsDesktopServices(ctx context.Context) ([]types.WindowsDesktopService, error) { resp, err := c.grpc.GetWindowsDesktopServices(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } services := make([]types.WindowsDesktopService, 0, len(resp.GetServices())) for _, service := range resp.GetServices() { @@ -2854,7 +2856,7 @@ func (c *Client) GetWindowsDesktopServices(ctx context.Context) ([]types.Windows func (c *Client) GetWindowsDesktopService(ctx context.Context, name string) (types.WindowsDesktopService, error) { resp, err := c.grpc.GetWindowsDesktopService(ctx, &proto.GetWindowsDesktopServiceRequest{Name: name}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.GetService(), nil } @@ -2867,7 +2869,7 @@ func (c *Client) UpsertWindowsDesktopService(ctx context.Context, service types. } keepAlive, err := c.grpc.UpsertWindowsDesktopService(ctx, s) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return keepAlive, nil } @@ -2878,7 +2880,7 @@ func (c *Client) DeleteWindowsDesktopService(ctx context.Context, name string) e Name: name, }) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -2887,7 +2889,7 @@ func (c *Client) DeleteWindowsDesktopService(ctx context.Context, name string) e func (c *Client) DeleteAllWindowsDesktopServices(ctx context.Context) error { _, err := c.grpc.DeleteAllWindowsDesktopServices(ctx, &emptypb.Empty{}) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -2896,7 +2898,7 @@ func (c *Client) DeleteAllWindowsDesktopServices(ctx context.Context) error { func (c *Client) GetWindowsDesktops(ctx context.Context, filter types.WindowsDesktopFilter) ([]types.WindowsDesktop, error) { resp, err := c.grpc.GetWindowsDesktops(ctx, &filter) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } desktops := make([]types.WindowsDesktop, 0, len(resp.GetDesktops())) for _, desktop := range resp.GetDesktops() { @@ -2912,7 +2914,7 @@ func (c *Client) CreateWindowsDesktop(ctx context.Context, desktop types.Windows return trace.BadParameter("invalid type %T", desktop) } _, err := c.grpc.CreateWindowsDesktop(ctx, d) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpdateWindowsDesktop updates an existing windows desktop host. @@ -2922,7 +2924,7 @@ func (c *Client) UpdateWindowsDesktop(ctx context.Context, desktop types.Windows return trace.BadParameter("invalid type %T", desktop) } _, err := c.grpc.UpdateWindowsDesktop(ctx, d) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpsertWindowsDesktop updates a windows desktop resource, creating it if it doesn't exist. @@ -2932,7 +2934,7 @@ func (c *Client) UpsertWindowsDesktop(ctx context.Context, desktop types.Windows return trace.BadParameter("invalid type %T", desktop) } _, err := c.grpc.UpsertWindowsDesktop(ctx, d) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteWindowsDesktop removes the specified windows desktop host. @@ -2945,7 +2947,7 @@ func (c *Client) DeleteWindowsDesktop(ctx context.Context, hostID, name string) HostID: hostID, }) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -2954,7 +2956,7 @@ func (c *Client) DeleteWindowsDesktop(ctx context.Context, hostID, name string) func (c *Client) DeleteAllWindowsDesktops(ctx context.Context) error { _, err := c.grpc.DeleteAllWindowsDesktops(ctx, &emptypb.Empty{}) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -2963,7 +2965,7 @@ func (c *Client) DeleteAllWindowsDesktops(ctx context.Context) error { func (c *Client) GenerateWindowsDesktopCert(ctx context.Context, req *proto.WindowsDesktopCertRequest) (*proto.WindowsDesktopCertResponse, error) { resp, err := c.grpc.GenerateWindowsDesktopCert(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -2972,7 +2974,7 @@ func (c *Client) GenerateWindowsDesktopCert(ctx context.Context, req *proto.Wind // Upon success, creates new web session and creates new set of recovery codes (if user meets requirements). func (c *Client) ChangeUserAuthentication(ctx context.Context, req *proto.ChangeUserAuthenticationRequest) (*proto.ChangeUserAuthenticationResponse, error) { res, err := c.grpc.ChangeUserAuthentication(ctx, req) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // StartAccountRecovery creates a recovery start token for a user who successfully verified their username and their recovery code. @@ -2980,7 +2982,7 @@ func (c *Client) ChangeUserAuthentication(ctx context.Context, req *proto.Change // Represents step 1 of the account recovery process. func (c *Client) StartAccountRecovery(ctx context.Context, req *proto.StartAccountRecoveryRequest) (types.UserToken, error) { res, err := c.grpc.StartAccountRecovery(ctx, req) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // VerifyAccountRecovery creates a recovery approved token after successful verification of users password or second factor @@ -2988,7 +2990,7 @@ func (c *Client) StartAccountRecovery(ctx context.Context, req *proto.StartAccou // Represents step 2 of the account recovery process after RPC StartAccountRecovery. func (c *Client) VerifyAccountRecovery(ctx context.Context, req *proto.VerifyAccountRecoveryRequest) (types.UserToken, error) { res, err := c.grpc.VerifyAccountRecovery(ctx, req) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // CompleteAccountRecovery sets a new password or adds a new mfa device, @@ -2996,50 +2998,50 @@ func (c *Client) VerifyAccountRecovery(ctx context.Context, req *proto.VerifyAcc // Represents the last step in the account recovery process after RPC's StartAccountRecovery and VerifyAccountRecovery. func (c *Client) CompleteAccountRecovery(ctx context.Context, req *proto.CompleteAccountRecoveryRequest) error { _, err := c.grpc.CompleteAccountRecovery(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // CreateAccountRecoveryCodes creates new set of recovery codes for a user, replacing and invalidating any previously owned codes. func (c *Client) CreateAccountRecoveryCodes(ctx context.Context, req *proto.CreateAccountRecoveryCodesRequest) (*proto.RecoveryCodes, error) { res, err := c.grpc.CreateAccountRecoveryCodes(ctx, req) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // GetAccountRecoveryToken returns a user token resource after verifying the token in // request is not expired and is of the correct recovery type. func (c *Client) GetAccountRecoveryToken(ctx context.Context, req *proto.GetAccountRecoveryTokenRequest) (types.UserToken, error) { res, err := c.grpc.GetAccountRecoveryToken(ctx, req) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // GetAccountRecoveryCodes returns the user in context their recovery codes resource without any secrets. func (c *Client) GetAccountRecoveryCodes(ctx context.Context, req *proto.GetAccountRecoveryCodesRequest) (*proto.RecoveryCodes, error) { res, err := c.grpc.GetAccountRecoveryCodes(ctx, req) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // CreateAuthenticateChallenge creates and returns MFA challenges for a users registered MFA devices. func (c *Client) CreateAuthenticateChallenge(ctx context.Context, in *proto.CreateAuthenticateChallengeRequest) (*proto.MFAAuthenticateChallenge, error) { resp, err := c.grpc.CreateAuthenticateChallenge(ctx, in) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // CreatePrivilegeToken is implemented by AuthService.CreatePrivilegeToken. func (c *Client) CreatePrivilegeToken(ctx context.Context, req *proto.CreatePrivilegeTokenRequest) (*types.UserTokenV3, error) { resp, err := c.grpc.CreatePrivilegeToken(ctx, req) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // CreateRegisterChallenge creates and returns MFA register challenge for a new MFA device. func (c *Client) CreateRegisterChallenge(ctx context.Context, in *proto.CreateRegisterChallengeRequest) (*proto.MFARegisterChallenge, error) { resp, err := c.grpc.CreateRegisterChallenge(ctx, in) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // GenerateCertAuthorityCRL generates an empty CRL for a CA. func (c *Client) GenerateCertAuthorityCRL(ctx context.Context, req *proto.CertAuthorityRequest) (*proto.CRL, error) { resp, err := c.grpc.GenerateCertAuthorityCRL(ctx, req) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // ListResources returns a paginated list of nodes that the user has access to. @@ -3055,7 +3057,7 @@ func (c *Client) ListResources(ctx context.Context, req proto.ListResourcesReque resp, err := c.grpc.ListResources(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } resources := make([]types.ResourceWithLabels, len(resp.GetResources())) @@ -3104,7 +3106,7 @@ func (c *Client) GetResources(ctx context.Context, req *proto.ListResourcesReque } resp, err := c.grpc.ListResources(ctx, req) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // ListUnifiedResources returns a paginated list of unified resources that the user has access to. @@ -3118,7 +3120,7 @@ func (c *Client) ListUnifiedResources(ctx context.Context, req *proto.ListUnifie } resp, err := c.grpc.ListUnifiedResources(ctx, req) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // GetResourcesClient is an interface used by GetResources to abstract over implementations of @@ -3202,13 +3204,13 @@ func ListUnifiedResourcePage(ctx context.Context, clt ListUnifiedResourcesClient req.Limit /= 2 // This is an extremely unlikely scenario, but better to cover it anyways. if req.Limit == 0 { - return out, trace.Wrap(trail.FromGRPC(err), "resource is too large to retrieve") + return out, trace.Wrap(trace.Wrap(err), "resource is too large to retrieve") } continue } - return out, trail.FromGRPC(err) + return out, trace.Wrap(err) } for _, respResource := range resp.Resources { @@ -3243,13 +3245,13 @@ func GetResourcePage[T types.ResourceWithLabels](ctx context.Context, clt GetRes req.Limit /= 2 // This is an extremely unlikely scenario, but better to cover it anyways. if req.Limit == 0 { - return out, trace.Wrap(trail.FromGRPC(err), "resource is too large to retrieve") + return out, trace.Wrap(trace.Wrap(err), "resource is too large to retrieve") } continue } - return out, trail.FromGRPC(err) + return out, trace.Wrap(err) } for _, respResource := range resp.Resources { @@ -3356,13 +3358,13 @@ func GetResourcesWithFilters(ctx context.Context, clt ListResourcesClient, req p chunkSize = chunkSize / 2 // This is an extremely unlikely scenario, but better to cover it anyways. if chunkSize == 0 { - return nil, trace.Wrap(trail.FromGRPC(err), "resource is too large to retrieve") + return nil, trace.Wrap(trace.Wrap(err), "resource is too large to retrieve") } continue } - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } startKey = resp.NextKey @@ -3407,11 +3409,11 @@ func GetKubernetesResourcesWithFilters(ctx context.Context, clt kubeproto.KubeSe chunkSize = chunkSize / 2 // This is an extremely unlikely scenario, but better to cover it anyways. if chunkSize == 0 { - return nil, trace.Wrap(trail.FromGRPC(err), "resource is too large to retrieve") + return nil, trace.Wrap(trace.Wrap(err), "resource is too large to retrieve") } continue } - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } startKey = resp.NextKey @@ -3430,7 +3432,7 @@ func GetKubernetesResourcesWithFilters(ctx context.Context, clt kubeproto.KubeSe // but may result in confusing behavior if it is used outside of those contexts. func (c *Client) GetSSHTargets(ctx context.Context, req *proto.GetSSHTargetsRequest) (*proto.GetSSHTargetsResponse, error) { rsp, err := c.grpc.GetSSHTargets(ctx, req) - if err := trail.FromGRPC(err); !trace.IsNotImplemented(err) { + if err := trace.Wrap(err); !trace.IsNotImplemented(err) { return rsp, err } @@ -3472,7 +3474,7 @@ func (c *Client) CreateSessionTracker(ctx context.Context, st types.SessionTrack req := &proto.CreateSessionTrackerRequest{SessionTracker: v1} tracker, err := c.grpc.CreateSessionTracker(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return tracker, nil } @@ -3482,7 +3484,7 @@ func (c *Client) GetSessionTracker(ctx context.Context, sessionID string) (types req := &proto.GetSessionTrackerRequest{SessionID: sessionID} resp, err := c.grpc.GetSessionTracker(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -3491,7 +3493,7 @@ func (c *Client) GetSessionTracker(ctx context.Context, sessionID string) (types func (c *Client) GetActiveSessionTrackers(ctx context.Context) ([]types.SessionTracker, error) { stream, err := c.grpc.GetActiveSessionTrackers(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } var sessions []types.SessionTracker @@ -3515,7 +3517,7 @@ func (c *Client) GetActiveSessionTrackers(ctx context.Context) ([]types.SessionT func (c *Client) GetActiveSessionTrackersWithFilter(ctx context.Context, filter *types.SessionTrackerFilter) ([]types.SessionTracker, error) { stream, err := c.grpc.GetActiveSessionTrackersWithFilter(ctx, filter) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } var sessions []types.SessionTracker @@ -3538,26 +3540,26 @@ func (c *Client) GetActiveSessionTrackersWithFilter(ctx context.Context, filter // RemoveSessionTracker removes a tracker resource for an active session. func (c *Client) RemoveSessionTracker(ctx context.Context, sessionID string) error { _, err := c.grpc.RemoveSessionTracker(ctx, &proto.RemoveSessionTrackerRequest{SessionID: sessionID}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpdateSessionTracker updates a tracker resource for an active session. func (c *Client) UpdateSessionTracker(ctx context.Context, req *proto.UpdateSessionTrackerRequest) error { _, err := c.grpc.UpdateSessionTracker(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // MaintainSessionPresence establishes a channel used to continuously verify the presence for a session. func (c *Client) MaintainSessionPresence(ctx context.Context) (proto.AuthService_MaintainSessionPresenceClient, error) { stream, err := c.grpc.MaintainSessionPresence(ctx) - return stream, trail.FromGRPC(err) + return stream, trace.Wrap(err) } // GetDomainName returns local auth domain of the current auth server func (c *Client) GetDomainName(ctx context.Context) (string, error) { resp, err := c.grpc.GetDomainName(ctx, &emptypb.Empty{}) if err != nil { - return "", trail.FromGRPC(err) + return "", trace.Wrap(err) } return resp.DomainName, nil } @@ -3567,7 +3569,7 @@ func (c *Client) GetDomainName(ctx context.Context) (string, error) { func (c *Client) GetClusterCACert(ctx context.Context) (*proto.GetClusterCACertResponse, error) { resp, err := c.grpc.GetClusterCACert(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -3578,7 +3580,7 @@ func (c *Client) GetConnectionDiagnostic(ctx context.Context, name string) (type Name: name, } res, err := c.grpc.GetConnectionDiagnostic(ctx, req) - return res, trail.FromGRPC(err) + return res, trace.Wrap(err) } // CreateConnectionDiagnostic creates a new connection diagnostic. @@ -3588,7 +3590,7 @@ func (c *Client) CreateConnectionDiagnostic(ctx context.Context, connectionDiagn return trace.BadParameter("invalid type %T", connectionDiagnostic) } _, err := c.grpc.CreateConnectionDiagnostic(ctx, connectionDiagnosticV1) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpdateConnectionDiagnostic updates a connection diagnostic. @@ -3598,7 +3600,7 @@ func (c *Client) UpdateConnectionDiagnostic(ctx context.Context, connectionDiagn return trace.BadParameter("invalid type %T", connectionDiagnostic) } _, err := c.grpc.UpdateConnectionDiagnostic(ctx, connectionDiagnosticV1) - return trail.FromGRPC(err) + return trace.Wrap(err) } // AppendDiagnosticTrace adds a new trace for the given ConnectionDiagnostic. @@ -3619,7 +3621,7 @@ func (c *Client) AppendDiagnosticTrace(ctx context.Context, name string, t *type func (c *Client) GetClusterAlerts(ctx context.Context, query types.GetClusterAlertsRequest) ([]types.ClusterAlert, error) { rsp, err := c.grpc.GetClusterAlerts(ctx, &query) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return rsp.Alerts, nil } @@ -3629,26 +3631,26 @@ func (c *Client) UpsertClusterAlert(ctx context.Context, alert types.ClusterAler _, err := c.grpc.UpsertClusterAlert(ctx, &proto.UpsertClusterAlertRequest{ Alert: alert, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } func (c *Client) ChangePassword(ctx context.Context, req *proto.ChangePasswordRequest) error { _, err := c.grpc.ChangePassword(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // SubmitUsageEvent submits an external usage event. func (c *Client) SubmitUsageEvent(ctx context.Context, req *proto.SubmitUsageEventRequest) error { _, err := c.grpc.SubmitUsageEvent(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetLicense returns the license used to start the teleport enterprise auth server func (c *Client) GetLicense(ctx context.Context) (string, error) { resp, err := c.grpc.GetLicense(ctx, &proto.GetLicenseRequest{}) if err != nil { - return "", trail.FromGRPC(err) + return "", trace.Wrap(err) } return string(resp.License), nil } @@ -3657,7 +3659,7 @@ func (c *Client) GetLicense(ctx context.Context) (string, error) { func (c *Client) ListReleases(ctx context.Context, req *proto.ListReleasesRequest) ([]*types.Release, error) { resp, err := c.grpc.ListReleases(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.Releases, nil @@ -3666,14 +3668,14 @@ func (c *Client) ListReleases(ctx context.Context, req *proto.ListReleasesReques // CreateAlertAck marks a cluster alert as acknowledged. func (c *Client) CreateAlertAck(ctx context.Context, ack types.AlertAcknowledgement) error { _, err := c.grpc.CreateAlertAck(ctx, &ack) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GetAlertAcks gets active alert acknowledgements. func (c *Client) GetAlertAcks(ctx context.Context) ([]types.AlertAcknowledgement, error) { rsp, err := c.grpc.GetAlertAcks(ctx, &proto.GetAlertAcksRequest{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return rsp.Acks, nil } @@ -3681,7 +3683,7 @@ func (c *Client) GetAlertAcks(ctx context.Context) ([]types.AlertAcknowledgement // ClearAlertAcks clears alert acknowledgments. func (c *Client) ClearAlertAcks(ctx context.Context, req proto.ClearAlertAcksRequest) error { _, err := c.grpc.ClearAlertAcks(ctx, &req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // ListSAMLIdPServiceProviders returns a paginated list of SAML IdP service provider resources. @@ -3691,7 +3693,7 @@ func (c *Client) ListSAMLIdPServiceProviders(ctx context.Context, pageSize int, NextKey: nextKey, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } serviceProviders := make([]types.SAMLIdPServiceProvider, 0, len(resp.GetServiceProviders())) for _, sp := range resp.GetServiceProviders() { @@ -3706,7 +3708,7 @@ func (c *Client) GetSAMLIdPServiceProvider(ctx context.Context, name string) (ty Name: name, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return sp, nil } @@ -3720,7 +3722,7 @@ func (c *Client) CreateSAMLIdPServiceProvider(ctx context.Context, sp types.SAML _, err := c.grpc.CreateSAMLIdPServiceProvider(ctx, spV1) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3734,7 +3736,7 @@ func (c *Client) UpdateSAMLIdPServiceProvider(ctx context.Context, sp types.SAML _, err := c.grpc.UpdateSAMLIdPServiceProvider(ctx, spV1) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3745,7 +3747,7 @@ func (c *Client) DeleteSAMLIdPServiceProvider(ctx context.Context, name string) Name: name, }) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3754,7 +3756,7 @@ func (c *Client) DeleteSAMLIdPServiceProvider(ctx context.Context, name string) func (c *Client) DeleteAllSAMLIdPServiceProviders(ctx context.Context) error { _, err := c.grpc.DeleteAllSAMLIdPServiceProviders(ctx, &emptypb.Empty{}) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3766,7 +3768,7 @@ func (c *Client) ListUserGroups(ctx context.Context, pageSize int, nextKey strin NextKey: nextKey, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } userGroups := make([]types.UserGroup, 0, len(resp.GetUserGroups())) for _, ug := range resp.GetUserGroups() { @@ -3781,7 +3783,7 @@ func (c *Client) GetUserGroup(ctx context.Context, name string) (types.UserGroup Name: name, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return ug, nil } @@ -3795,7 +3797,7 @@ func (c *Client) CreateUserGroup(ctx context.Context, ug types.UserGroup) error _, err := c.grpc.CreateUserGroup(ctx, ugV1) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3809,7 +3811,7 @@ func (c *Client) UpdateUserGroup(ctx context.Context, ug types.UserGroup) error _, err := c.grpc.UpdateUserGroup(ctx, ugV1) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3820,7 +3822,7 @@ func (c *Client) DeleteUserGroup(ctx context.Context, name string) error { Name: name, }) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3829,7 +3831,7 @@ func (c *Client) DeleteUserGroup(ctx context.Context, name string) error { func (c *Client) DeleteAllUserGroups(ctx context.Context) error { _, err := c.grpc.DeleteAllUserGroups(ctx, &emptypb.Empty{}) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -3839,7 +3841,7 @@ func (c *Client) DeleteAllUserGroups(ctx context.Context) error { func (c *Client) ExportUpgradeWindows(ctx context.Context, req proto.ExportUpgradeWindowsRequest) (proto.ExportUpgradeWindowsResponse, error) { rsp, err := c.grpc.ExportUpgradeWindows(ctx, &req) if err != nil { - return proto.ExportUpgradeWindowsResponse{}, trail.FromGRPC(err) + return proto.ExportUpgradeWindowsResponse{}, trace.Wrap(err) } return *rsp, nil } @@ -3848,7 +3850,7 @@ func (c *Client) ExportUpgradeWindows(ctx context.Context, req proto.ExportUpgra func (c *Client) GetClusterMaintenanceConfig(ctx context.Context) (types.ClusterMaintenanceConfig, error) { rsp, err := c.grpc.GetClusterMaintenanceConfig(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return rsp, nil } @@ -3861,13 +3863,13 @@ func (c *Client) UpdateClusterMaintenanceConfig(ctx context.Context, cmc types.C } _, err := c.grpc.UpdateClusterMaintenanceConfig(ctx, req) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteClusterMaintenanceConfig deletes the current maintenance window config singleton. func (c *Client) DeleteClusterMaintenanceConfig(ctx context.Context) error { _, err := c.grpc.DeleteClusterMaintenanceConfig(ctx, &emptypb.Empty{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // integrationsClient returns an unadorned Integration client, using the underlying @@ -3884,7 +3886,7 @@ func (c *Client) ListIntegrations(ctx context.Context, pageSize int, nextKey str NextKey: nextKey, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } integrations := make([]types.Integration, 0, len(resp.GetIntegrations())) @@ -3901,7 +3903,7 @@ func (c *Client) GetIntegration(ctx context.Context, name string) (types.Integra Name: name, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return ig, nil @@ -3916,7 +3918,7 @@ func (c *Client) CreateIntegration(ctx context.Context, ig types.Integration) (t ig, err := c.integrationsClient().CreateIntegration(ctx, &integrationpb.CreateIntegrationRequest{Integration: igV1}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return ig, nil @@ -3931,7 +3933,7 @@ func (c *Client) UpdateIntegration(ctx context.Context, ig types.Integration) (t ig, err := c.integrationsClient().UpdateIntegration(ctx, &integrationpb.UpdateIntegrationRequest{Integration: igV1}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return ig, nil @@ -3942,13 +3944,13 @@ func (c *Client) DeleteIntegration(ctx context.Context, name string) error { _, err := c.integrationsClient().DeleteIntegration(ctx, &integrationpb.DeleteIntegrationRequest{ Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllIntegrations removes all Integrations. func (c *Client) DeleteAllIntegrations(ctx context.Context) error { _, err := c.integrationsClient().DeleteAllIntegrations(ctx, &integrationpb.DeleteAllIntegrationsRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // GenerateAWSOIDCToken generates a token to be used when executing an AWS OIDC Integration action. @@ -3957,7 +3959,7 @@ func (c *Client) GenerateAWSOIDCToken(ctx context.Context, req types.GenerateAWS Issuer: req.Issuer, }) if err != nil { - return "", trail.FromGRPC(err) + return "", trace.Wrap(err) } return resp.GetToken(), nil @@ -3977,7 +3979,7 @@ func (c *Client) GetLoginRule(ctx context.Context, name string) (*loginrulepb.Lo rule, err := c.LoginRuleClient().GetLoginRule(ctx, &loginrulepb.GetLoginRuleRequest{ Name: name, }) - return rule, trail.FromGRPC(err) + return rule, trace.Wrap(err) } // CreateLoginRule creates a login rule if one with the same name does not @@ -3986,7 +3988,7 @@ func (c *Client) CreateLoginRule(ctx context.Context, rule *loginrulepb.LoginRul rule, err := c.LoginRuleClient().CreateLoginRule(ctx, &loginrulepb.CreateLoginRuleRequest{ LoginRule: rule, }) - return rule, trail.FromGRPC(err) + return rule, trace.Wrap(err) } // UpsertLoginRule creates a login rule if one with the same name does not @@ -3995,7 +3997,7 @@ func (c *Client) UpsertLoginRule(ctx context.Context, rule *loginrulepb.LoginRul rule, err := c.LoginRuleClient().UpsertLoginRule(ctx, &loginrulepb.UpsertLoginRuleRequest{ LoginRule: rule, }) - return rule, trail.FromGRPC(err) + return rule, trace.Wrap(err) } // DeleteLoginRule deletes an existing login rule by name. @@ -4003,7 +4005,7 @@ func (c *Client) DeleteLoginRule(ctx context.Context, name string) error { _, err := c.LoginRuleClient().DeleteLoginRule(ctx, &loginrulepb.DeleteLoginRuleRequest{ Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // OktaClient returns an Okta client. @@ -4038,7 +4040,7 @@ func (c *Client) GetCertAuthority(ctx context.Context, id types.CertAuthID, load IncludeKey: loadKeys, }) - return ca, trail.FromGRPC(err) + return ca, trace.Wrap(err) } // GetCertAuthorities retrieves CAs by type. @@ -4048,7 +4050,7 @@ func (c *Client) GetCertAuthorities(ctx context.Context, caType types.CertAuthTy IncludeKey: loadKeys, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } cas := make([]types.CertAuthority, 0, len(resp.CertAuthoritiesV2)) @@ -4066,7 +4068,7 @@ func (c *Client) DeleteCertAuthority(ctx context.Context, id types.CertAuthID) e Domain: id.DomainName, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // UpsertCertAuthority creates or updates the provided cert authority. @@ -4080,7 +4082,7 @@ func (c *Client) UpsertCertAuthority(ctx context.Context, ca types.CertAuthority CertAuthority: cav2, }) - return out, trail.FromGRPC(err) + return out, trace.Wrap(err) } // UpdateHeadlessAuthenticationState updates a headless authentication state. @@ -4091,7 +4093,7 @@ func (c *Client) UpdateHeadlessAuthenticationState(ctx context.Context, id strin MfaResponse: mfaResponse, }) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -4102,7 +4104,7 @@ func (c *Client) GetHeadlessAuthentication(ctx context.Context, id string) (*typ Id: id, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return headlessAuthn, nil } @@ -4113,7 +4115,7 @@ func (c *Client) WatchPendingHeadlessAuthentications(ctx context.Context) (types stream, err := c.grpc.WatchPendingHeadlessAuthentications(cancelCtx, &emptypb.Empty{}) if err != nil { cancel() - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } w := &streamWatcher{ stream: stream, @@ -4129,7 +4131,7 @@ func (c *Client) WatchPendingHeadlessAuthentications(ctx context.Context) (types func (c *Client) CreateAssistantConversation(ctx context.Context, req *assist.CreateAssistantConversationRequest) (*assist.CreateAssistantConversationResponse, error) { resp, err := c.grpc.CreateAssistantConversation(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil @@ -4139,7 +4141,7 @@ func (c *Client) CreateAssistantConversation(ctx context.Context, req *assist.Cr func (c *Client) GetAssistantMessages(ctx context.Context, req *assist.GetAssistantMessagesRequest) (*assist.GetAssistantMessagesResponse, error) { messages, err := c.grpc.GetAssistantMessages(ctx, req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return messages, nil } @@ -4148,7 +4150,7 @@ func (c *Client) GetAssistantMessages(ctx context.Context, req *assist.GetAssist func (c *Client) DeleteAssistantConversation(ctx context.Context, req *assist.DeleteAssistantConversationRequest) error { _, err := c.grpc.DeleteAssistantConversation(ctx, req) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -4157,7 +4159,7 @@ func (c *Client) DeleteAssistantConversation(ctx context.Context, req *assist.De func (c *Client) IsAssistEnabled(ctx context.Context) (*assist.IsAssistEnabledResponse, error) { resp, err := c.grpc.IsAssistEnabled(ctx, &assist.IsAssistEnabledRequest{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -4166,7 +4168,7 @@ func (c *Client) IsAssistEnabled(ctx context.Context) (*assist.IsAssistEnabledRe func (c *Client) GetAssistantConversations(ctx context.Context, request *assist.GetAssistantConversationsRequest) (*assist.GetAssistantConversationsResponse, error) { messages, err := c.grpc.GetAssistantConversations(ctx, request) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return messages, nil } @@ -4175,7 +4177,7 @@ func (c *Client) GetAssistantConversations(ctx context.Context, request *assist. func (c *Client) CreateAssistantMessage(ctx context.Context, in *assist.CreateAssistantMessageRequest) error { _, err := c.grpc.CreateAssistantMessage(ctx, in) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -4184,7 +4186,7 @@ func (c *Client) CreateAssistantMessage(ctx context.Context, in *assist.CreateAs func (c *Client) UpdateAssistantConversationInfo(ctx context.Context, in *assist.UpdateAssistantConversationInfoRequest) error { _, err := c.grpc.UpdateAssistantConversationInfo(ctx, in) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -4192,7 +4194,7 @@ func (c *Client) UpdateAssistantConversationInfo(ctx context.Context, in *assist func (c *Client) GetAssistantEmbeddings(ctx context.Context, in *assist.GetAssistantEmbeddingsRequest) (*assist.GetAssistantEmbeddingsResponse, error) { result, err := c.EmbeddingClient().GetAssistantEmbeddings(ctx, in) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return result, nil } @@ -4201,7 +4203,7 @@ func (c *Client) GetAssistantEmbeddings(ctx context.Context, in *assist.GetAssis func (c *Client) GetUserPreferences(ctx context.Context, in *userpreferencespb.GetUserPreferencesRequest) (*userpreferencespb.GetUserPreferencesResponse, error) { resp, err := c.grpc.GetUserPreferences(ctx, in) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp, nil } @@ -4210,7 +4212,7 @@ func (c *Client) GetUserPreferences(ctx context.Context, in *userpreferencespb.G func (c *Client) UpsertUserPreferences(ctx context.Context, in *userpreferencespb.UpsertUserPreferencesRequest) error { _, err := c.grpc.UpsertUserPreferences(ctx, in) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } diff --git a/api/client/inventory.go b/api/client/inventory.go index d44ef70e60db..da9e9bdd6ff2 100644 --- a/api/client/inventory.go +++ b/api/client/inventory.go @@ -23,7 +23,6 @@ import ( "sync" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/internalutils/stream" @@ -201,7 +200,7 @@ func (c *Client) InventoryControlStream(ctx context.Context) (DownstreamInventor stream, err := c.grpc.InventoryControlStream(cancelCtx) if err != nil { cancel() - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return newDownstreamInventoryControlStream(stream, cancel), nil } @@ -209,7 +208,7 @@ func (c *Client) InventoryControlStream(ctx context.Context) (DownstreamInventor func (c *Client) GetInventoryStatus(ctx context.Context, req proto.InventoryStatusRequest) (proto.InventoryStatusSummary, error) { rsp, err := c.grpc.GetInventoryStatus(ctx, &req) if err != nil { - return proto.InventoryStatusSummary{}, trail.FromGRPC(err) + return proto.InventoryStatusSummary{}, trace.Wrap(err) } return *rsp, nil @@ -218,7 +217,7 @@ func (c *Client) GetInventoryStatus(ctx context.Context, req proto.InventoryStat func (c *Client) PingInventory(ctx context.Context, req proto.InventoryPingRequest) (proto.InventoryPingResponse, error) { rsp, err := c.grpc.PingInventory(ctx, &req) if err != nil { - return proto.InventoryPingResponse{}, trail.FromGRPC(err) + return proto.InventoryPingResponse{}, trace.Wrap(err) } return *rsp, nil @@ -232,7 +231,7 @@ func (c *Client) GetInstances(ctx context.Context, filter types.InstanceFilter) instances, err := c.grpc.GetInstances(ctx, &filter) if err != nil { cancel() - return stream.Fail[types.Instance](trail.FromGRPC(err)) + return stream.Fail[types.Instance](trace.Wrap(err)) } return stream.Func[types.Instance](func() (types.Instance, error) { instance, err := instances.Recv() @@ -241,7 +240,7 @@ func (c *Client) GetInstances(ctx context.Context, filter types.InstanceFilter) // io.EOF signals that stream has completed successfully return nil, io.EOF } - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return instance, nil }, cancel) @@ -286,7 +285,7 @@ func (i *downstreamICS) runRecvLoop(stream proto.AuthService_InventoryControlStr if err != nil { // preserve EOF to help distinguish "ok" closure. if !errors.Is(err, io.EOF) { - err = trace.Errorf("inventory control stream closed: %v", trail.FromGRPC(err)) + err = trace.Errorf("inventory control stream closed: %v", trace.Wrap(err)) } i.CloseWithError(err) return @@ -344,7 +343,7 @@ func (i *downstreamICS) runSendLoop(stream proto.AuthService_InventoryControlStr sendMsg.errC <- trace.BadParameter("cannot send unexpected upstream msg type: %T", msg) continue } - err := trail.FromGRPC(stream.Send(&oneOf)) + err := stream.Send(&oneOf) sendMsg.errC <- err if err != nil { // preserve EOF errors @@ -418,7 +417,7 @@ func (i *downstreamICS) Error() error { } // NewUpstreamInventoryControlStream wraps the server-side control stream handle. For use as part of the internals -// of the auth server's GRPC API implementation. +// of the auth server's gRPC API implementation. func NewUpstreamInventoryControlStream(stream proto.AuthService_InventoryControlStreamServer, peerAddr string) UpstreamInventoryControlStream { ics := &upstreamICS{ sendC: make(chan downstreamSend), @@ -458,7 +457,7 @@ func (i *upstreamICS) runRecvLoop(stream proto.AuthService_InventoryControlStrea if err != nil { // preserve eof errors if !errors.Is(err, io.EOF) { - err = trace.Errorf("inventory control stream recv failed: %v", trail.FromGRPC(err)) + err = trace.Errorf("inventory control stream recv failed: %v", trace.Wrap(err)) } i.CloseWithError(err) return @@ -514,7 +513,7 @@ func (i *upstreamICS) runSendLoop(stream proto.AuthService_InventoryControlStrea sendMsg.errC <- trace.BadParameter("cannot send unexpected upstream msg type: %T", msg) continue } - err := trail.FromGRPC(stream.Send(&oneOf)) + err := stream.Send(&oneOf) sendMsg.errC <- err if err != nil { // preserve eof errors diff --git a/api/client/keepaliver.go b/api/client/keepaliver.go index d9a6bb98c357..b5d376a49a20 100644 --- a/api/client/keepaliver.go +++ b/api/client/keepaliver.go @@ -20,7 +20,7 @@ import ( "context" "sync" - "github.com/gravitational/trace/trail" + "github.com/gravitational/trace" "google.golang.org/protobuf/types/known/emptypb" "github.com/gravitational/teleport/api/client/proto" @@ -35,7 +35,7 @@ func (c *Client) NewKeepAliver(ctx context.Context) (types.KeepAliver, error) { stream, err := c.grpc.SendKeepAlives(cancelCtx) if err != nil { cancel() - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } k := &streamKeepAliver{ stream: stream, @@ -70,7 +70,7 @@ func (k *streamKeepAliver) forwardKeepAlives() { case keepAlive := <-k.keepAlivesC: err := k.stream.Send(&keepAlive) if err != nil { - k.closeWithError(trail.FromGRPC(err)) + k.closeWithError(trace.Wrap(err)) return } } @@ -93,7 +93,7 @@ func (k *streamKeepAliver) Done() <-chan struct{} { // server, otherwise no errors will be propagated func (k *streamKeepAliver) recv() { err := k.stream.RecvMsg(&emptypb.Empty{}) - k.closeWithError(trail.FromGRPC(err)) + k.closeWithError(trace.Wrap(err)) } func (k *streamKeepAliver) closeWithError(err error) { diff --git a/api/client/mock_server_test.go b/api/client/mock_server_test.go index 4840961a9925..e4113a22ffe4 100644 --- a/api/client/mock_server_test.go +++ b/api/client/mock_server_test.go @@ -27,6 +27,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/testhelpers/mtls" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" ) // mockServer mocks an Auth Server. @@ -45,6 +46,8 @@ func newMockServer(t *testing.T, addr string, service proto.AuthServiceServer) * m.grpc = grpc.NewServer( grpc.Creds(credentials.NewTLS(m.mtlsConfig.ServerTLS)), + grpc.UnaryInterceptor(interceptors.GRPCServerUnaryErrorInterceptor), + grpc.StreamInterceptor(interceptors.GRPCServerStreamErrorInterceptor), ) proto.RegisterAuthServiceServer(m.grpc, service) diff --git a/api/client/okta/okta.go b/api/client/okta/okta.go index b2d7cb872705..641b4fe51ced 100644 --- a/api/client/okta/okta.go +++ b/api/client/okta/okta.go @@ -19,7 +19,6 @@ import ( "time" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "google.golang.org/protobuf/types/known/durationpb" oktapb "github.com/gravitational/teleport/api/gen/proto/go/teleport/okta/v1" @@ -47,7 +46,7 @@ func (c *Client) ListOktaImportRules(ctx context.Context, pageSize int, pageToke PageToken: pageToken, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } importRules := make([]types.OktaImportRule, len(resp.ImportRules)) @@ -63,7 +62,7 @@ func (c *Client) GetOktaImportRule(ctx context.Context, name string) (types.Okta resp, err := c.grpcClient.GetOktaImportRule(ctx, &oktapb.GetOktaImportRuleRequest{ Name: name, }) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // CreateOktaImportRule creates a new Okta import rule resource. @@ -75,7 +74,7 @@ func (c *Client) CreateOktaImportRule(ctx context.Context, importRule types.Okta resp, err := c.grpcClient.CreateOktaImportRule(ctx, &oktapb.CreateOktaImportRuleRequest{ ImportRule: importRuleV1, }) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // UpdateOktaImportRule updates an existing Okta import rule resource. @@ -87,7 +86,7 @@ func (c *Client) UpdateOktaImportRule(ctx context.Context, importRule types.Okta resp, err := c.grpcClient.UpdateOktaImportRule(ctx, &oktapb.UpdateOktaImportRuleRequest{ ImportRule: importRuleV1, }) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // DeleteOktaImportRule removes the specified Okta import rule resource. @@ -95,13 +94,13 @@ func (c *Client) DeleteOktaImportRule(ctx context.Context, name string) error { _, err := c.grpcClient.DeleteOktaImportRule(ctx, &oktapb.DeleteOktaImportRuleRequest{ Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllOktaImportRules removes all Okta import rules. func (c *Client) DeleteAllOktaImportRules(ctx context.Context) error { _, err := c.grpcClient.DeleteAllOktaImportRules(ctx, &oktapb.DeleteAllOktaImportRulesRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } // ListOktaAssignments returns a paginated list of all Okta assignment resources. @@ -111,7 +110,7 @@ func (c *Client) ListOktaAssignments(ctx context.Context, pageSize int, pageToke PageToken: pageToken, }) if err != nil { - return nil, "", trail.FromGRPC(err) + return nil, "", trace.Wrap(err) } assignments := make([]types.OktaAssignment, len(resp.Assignments)) @@ -127,7 +126,7 @@ func (c *Client) GetOktaAssignment(ctx context.Context, name string) (types.Okta resp, err := c.grpcClient.GetOktaAssignment(ctx, &oktapb.GetOktaAssignmentRequest{ Name: name, }) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // CreateOktaAssignmentcreates a new Okta assignment resource. @@ -139,7 +138,7 @@ func (c *Client) CreateOktaAssignment(ctx context.Context, assignment types.Okta resp, err := c.grpcClient.CreateOktaAssignment(ctx, &oktapb.CreateOktaAssignmentRequest{ Assignment: assignmentV1, }) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // UpdateOktaAssignmentupdates an existing Okta assignment resource. @@ -151,7 +150,7 @@ func (c *Client) UpdateOktaAssignment(ctx context.Context, assignment types.Okta resp, err := c.grpcClient.UpdateOktaAssignment(ctx, &oktapb.UpdateOktaAssignmentRequest{ Assignment: assignmentV1, }) - return resp, trail.FromGRPC(err) + return resp, trace.Wrap(err) } // UpdateOktaAssignmentStatus will update the status for an Okta assignment if the given time has passed @@ -162,7 +161,7 @@ func (c *Client) UpdateOktaAssignmentStatus(ctx context.Context, name, status st Status: types.OktaAssignmentStatusToProto(status), TimeHasPassed: durationpb.New(timeHasPassed), }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteOktaAssignmentremoves the specified Okta assignment resource. @@ -170,11 +169,11 @@ func (c *Client) DeleteOktaAssignment(ctx context.Context, name string) error { _, err := c.grpcClient.DeleteOktaAssignment(ctx, &oktapb.DeleteOktaAssignmentRequest{ Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllOktaAssignments removes all Okta assignments. func (c *Client) DeleteAllOktaAssignments(ctx context.Context) error { _, err := c.grpcClient.DeleteAllOktaAssignments(ctx, &oktapb.DeleteAllOktaAssignmentsRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } diff --git a/api/client/proxy/client.go b/api/client/proxy/client.go index 63d3848d2afe..d0d60e4ad6d8 100644 --- a/api/client/proxy/client.go +++ b/api/client/proxy/client.go @@ -38,6 +38,7 @@ import ( transportv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/transport/v1" "github.com/gravitational/teleport/api/metadata" "github.com/gravitational/teleport/api/observability/tracing" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" ) // ClientConfig contains configuration needed for a Client @@ -274,12 +275,14 @@ func newGRPCClient(ctx context.Context, cfg *ClientConfig) (_ *Client, err error append(cfg.UnaryInterceptors, otelgrpc.UnaryClientInterceptor(), metadata.UnaryClientInterceptor, + interceptors.GRPCClientUnaryErrorInterceptor, )..., ), grpc.WithChainStreamInterceptor( append(cfg.StreamInterceptors, otelgrpc.StreamClientInterceptor(), metadata.StreamClientInterceptor, + interceptors.GRPCClientStreamErrorInterceptor, )..., ), }, cfg.DialOpts...)..., diff --git a/api/client/proxy/transport/transportv1/client.go b/api/client/proxy/transport/transportv1/client.go index 285cc69651ae..60d39694364e 100644 --- a/api/client/proxy/transport/transportv1/client.go +++ b/api/client/proxy/transport/transportv1/client.go @@ -20,7 +20,6 @@ import ( "sync" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "golang.org/x/crypto/ssh/agent" "google.golang.org/grpc/peer" @@ -51,7 +50,7 @@ func NewClient(client transportv1pb.TransportServiceClient) (*Client, error) { func (c *Client) ClusterDetails(ctx context.Context) (*transportv1pb.ClusterDetails, error) { resp, err := c.clt.GetClusterDetails(ctx, &transportv1pb.GetClusterDetailsRequest{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.Details, nil @@ -62,11 +61,11 @@ func (c *Client) ClusterDetails(ctx context.Context) (*transportv1pb.ClusterDeta func (c *Client) DialCluster(ctx context.Context, cluster string, src net.Addr) (net.Conn, error) { stream, err := c.clt.ProxyCluster(ctx) if err != nil { - return nil, trail.FromGRPC(err, "unable to establish proxy stream") + return nil, trace.Wrap(err, "unable to establish proxy stream") } if err := stream.Send(&transportv1pb.ProxyClusterRequest{Cluster: cluster}); err != nil { - return nil, trail.FromGRPC(err, "failed to send cluster request") + return nil, trace.Wrap(err, "failed to send cluster request") } streamRW, err := streamutils.NewReadWriter(clusterStream{stream: stream}) @@ -115,19 +114,19 @@ func (c clusterStream) Close() error { func (c *Client) DialHost(ctx context.Context, hostport, cluster string, src net.Addr, keyring agent.ExtendedAgent) (net.Conn, *transportv1pb.ClusterDetails, error) { stream, err := c.clt.ProxySSH(ctx) if err != nil { - return nil, nil, trail.FromGRPC(err, "unable to establish proxy stream") + return nil, nil, trace.Wrap(err, "unable to establish proxy stream") } if err := stream.Send(&transportv1pb.ProxySSHRequest{DialTarget: &transportv1pb.TargetHost{ HostPort: hostport, Cluster: cluster, }}); err != nil { - return nil, nil, trail.FromGRPC(err, "failed to send dial target request") + return nil, nil, trace.Wrap(err, "failed to send dial target request") } resp, err := stream.Recv() if err != nil { - return nil, nil, trail.FromGRPC(err, "failed to receive cluster details response") + return nil, nil, trace.Wrap(err, "failed to receive cluster details response") } // create streams for ssh and agent protocol @@ -161,8 +160,8 @@ func (c *Client) DialHost(ctx context.Context, hostport, cluster string, src net for { req, err := stream.Recv() if err != nil { - sshStream.errorC <- trail.FromGRPC(err) - agentStream.errorC <- trail.FromGRPC(err) + sshStream.errorC <- trace.Wrap(err) + agentStream.errorC <- trace.Wrap(err) return } diff --git a/api/client/proxy/transport/transportv1/client_test.go b/api/client/proxy/transport/transportv1/client_test.go index b8e12ff4fc56..7d28b065aff7 100644 --- a/api/client/proxy/transport/transportv1/client_test.go +++ b/api/client/proxy/transport/transportv1/client_test.go @@ -37,6 +37,7 @@ import ( "google.golang.org/grpc/test/bufconn" transportv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/transport/v1" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" streamutils "github.com/gravitational/teleport/api/utils/grpc/stream" ) @@ -537,6 +538,8 @@ func newServer(t *testing.T, srv transportv1pb.TransportServiceServer) testPack }), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(1000)), grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(interceptors.GRPCClientUnaryErrorInterceptor), + grpc.WithStreamInterceptor(interceptors.GRPCClientStreamErrorInterceptor), ) require.NoError(t, err) t.Cleanup(func() { diff --git a/api/client/sessions.go b/api/client/sessions.go index 7ace339b18e7..84b8688f856f 100644 --- a/api/client/sessions.go +++ b/api/client/sessions.go @@ -20,7 +20,6 @@ import ( "context" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "google.golang.org/protobuf/types/known/emptypb" "github.com/gravitational/teleport/api/types" @@ -41,7 +40,7 @@ func (c *Client) WebSessions() types.WebSessionInterface { func (r *webSessions) Get(ctx context.Context, req types.GetWebSessionRequest) (types.WebSession, error) { resp, err := r.c.grpc.GetWebSession(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.Session, nil } @@ -50,7 +49,7 @@ func (r *webSessions) Get(ctx context.Context, req types.GetWebSessionRequest) ( func (r *webSessions) List(ctx context.Context) ([]types.WebSession, error) { resp, err := r.c.grpc.GetWebSessions(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } out := make([]types.WebSession, 0, len(resp.Sessions)) for _, session := range resp.Sessions { @@ -68,7 +67,7 @@ func (r *webSessions) Upsert(ctx context.Context, session types.WebSession) erro func (r *webSessions) Delete(ctx context.Context, req types.DeleteWebSessionRequest) error { _, err := r.c.grpc.DeleteWebSession(ctx, &req) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -77,7 +76,7 @@ func (r *webSessions) Delete(ctx context.Context, req types.DeleteWebSessionRequ func (r *webSessions) DeleteAll(ctx context.Context) error { _, err := r.c.grpc.DeleteAllWebSessions(ctx, &emptypb.Empty{}) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -101,7 +100,7 @@ func (c *Client) WebTokens() types.WebTokenInterface { func (r *webTokens) Get(ctx context.Context, req types.GetWebTokenRequest) (types.WebToken, error) { resp, err := r.c.grpc.GetWebToken(ctx, &req) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } return resp.Token, nil } @@ -110,7 +109,7 @@ func (r *webTokens) Get(ctx context.Context, req types.GetWebTokenRequest) (type func (r *webTokens) List(ctx context.Context) ([]types.WebToken, error) { resp, err := r.c.grpc.GetWebTokens(ctx, &emptypb.Empty{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } out := make([]types.WebToken, 0, len(resp.Tokens)) for _, token := range resp.Tokens { @@ -128,7 +127,7 @@ func (r *webTokens) Upsert(ctx context.Context, token types.WebToken) error { func (r *webTokens) Delete(ctx context.Context, req types.DeleteWebTokenRequest) error { _, err := r.c.grpc.DeleteWebToken(ctx, &req) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } @@ -137,7 +136,7 @@ func (r *webTokens) Delete(ctx context.Context, req types.DeleteWebTokenRequest) func (r *webTokens) DeleteAll(ctx context.Context) error { _, err := r.c.grpc.DeleteAllWebTokens(ctx, &emptypb.Empty{}) if err != nil { - return trail.FromGRPC(err) + return trace.Wrap(err) } return nil } diff --git a/api/client/streamwatcher.go b/api/client/streamwatcher.go index fbffdcaec797..d25b30baf632 100644 --- a/api/client/streamwatcher.go +++ b/api/client/streamwatcher.go @@ -21,7 +21,6 @@ import ( "sync" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" @@ -37,7 +36,7 @@ func (c *Client) NewWatcher(ctx context.Context, watch types.Watch) (types.Watch stream, err := c.grpc.WatchEvents(cancelCtx, &protoWatch) if err != nil { cancel() - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } w := &streamWatcher{ stream: stream, @@ -84,12 +83,12 @@ func (w *streamWatcher) receiveEvents() { for { event, err := w.stream.Recv() if err != nil { - w.closeWithError(trail.FromGRPC(err)) + w.closeWithError(trace.Wrap(err)) return } out, err := EventFromGRPC(event) if err != nil { - w.closeWithError(trail.FromGRPC(err)) + w.closeWithError(trace.Wrap(err)) return } select { diff --git a/api/client/userloginstate/userloginstate.go b/api/client/userloginstate/userloginstate.go index 677281ed1795..0850c7e58e8f 100644 --- a/api/client/userloginstate/userloginstate.go +++ b/api/client/userloginstate/userloginstate.go @@ -17,7 +17,7 @@ package userloginstate import ( "context" - "github.com/gravitational/trace/trail" + "github.com/gravitational/trace" userloginstatev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userloginstate/v1" "github.com/gravitational/teleport/api/types/userloginstate" @@ -41,7 +41,7 @@ func NewClient(grpcClient userloginstatev1.UserLoginStateServiceClient) *Client func (c *Client) GetUserLoginStates(ctx context.Context) ([]*userloginstate.UserLoginState, error) { resp, err := c.grpcClient.GetUserLoginStates(ctx, &userloginstatev1.GetUserLoginStatesRequest{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } ulsList := make([]*userloginstate.UserLoginState, len(resp.UserLoginStates)) @@ -49,7 +49,7 @@ func (c *Client) GetUserLoginStates(ctx context.Context) ([]*userloginstate.User var err error ulsList[i], err = conv.FromProto(uls) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } } @@ -62,21 +62,21 @@ func (c *Client) GetUserLoginState(ctx context.Context, name string) (*userlogin Name: name, }) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } uls, err := conv.FromProto(resp) - return uls, trail.FromGRPC(err) + return uls, trace.Wrap(err) } // UpsertUserLoginState creates or updates a user login state resource. func (c *Client) UpsertUserLoginState(ctx context.Context, uls *userloginstate.UserLoginState) (*userloginstate.UserLoginState, error) { resp, err := c.grpcClient.UpsertUserLoginState(ctx, &userloginstatev1.UpsertUserLoginStateRequest{}) if err != nil { - return nil, trail.FromGRPC(err) + return nil, trace.Wrap(err) } responseUls, err := conv.FromProto(resp) - return responseUls, trail.FromGRPC(err) + return responseUls, trace.Wrap(err) } // DeleteUserLoginState removes the specified user login state resource. @@ -84,11 +84,11 @@ func (c *Client) DeleteUserLoginState(ctx context.Context, name string) error { _, err := c.grpcClient.DeleteUserLoginState(ctx, &userloginstatev1.DeleteUserLoginStateRequest{ Name: name, }) - return trail.FromGRPC(err) + return trace.Wrap(err) } // DeleteAllUserLoginStates removes all user login states. func (c *Client) DeleteAllUserLoginStates(ctx context.Context) error { _, err := c.grpcClient.DeleteAllUserLoginStates(ctx, &userloginstatev1.DeleteAllUserLoginStatesRequest{}) - return trail.FromGRPC(err) + return trace.Wrap(err) } diff --git a/api/metadata/metadata.go b/api/metadata/metadata.go index 0f9983f078ef..328963ceb44a 100644 --- a/api/metadata/metadata.go +++ b/api/metadata/metadata.go @@ -53,7 +53,7 @@ func AddMetadataToContext(ctx context.Context, raw map[string]string) context.Co // to stop the client interceptors from adding any metadata to the context (useful for testing). type DisableInterceptors struct{} -// StreamServerInterceptor intercepts a GRPC client stream call and adds +// StreamServerInterceptor intercepts a gRPC client stream call and adds // default metadata to the context. func StreamServerInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { if disable := stream.Context().Value(DisableInterceptors{}); disable == nil { @@ -63,7 +63,7 @@ func StreamServerInterceptor(srv interface{}, stream grpc.ServerStream, info *gr return handler(srv, stream) } -// StreamClientInterceptor intercepts a GRPC client stream call and adds +// StreamClientInterceptor intercepts a gRPC client stream call and adds // default metadata to the context. func StreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { if disable := ctx.Value(DisableInterceptors{}); disable == nil { @@ -72,7 +72,7 @@ func StreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grp return streamer(ctx, desc, cc, method, opts...) } -// UnaryClientInterceptor intercepts a GRPC client unary call and adds default +// UnaryClientInterceptor intercepts a gRPC client unary call and adds default // metadata to the context. func UnaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { if disable := ctx.Value(DisableInterceptors{}); disable == nil { @@ -81,8 +81,8 @@ func UnaryClientInterceptor(ctx context.Context, method string, req, reply inter return invoker(ctx, method, req, reply, cc, opts...) } -// ClientVersionFromContext can be called from a GRPC server method to return -// the client version that was added to the GRPC metadata by +// ClientVersionFromContext can be called from a gRPC server method to return +// the client version that was added to the gRPC metadata by // StreamClientInterceptor or UnaryClientInterceptor on the client. func ClientVersionFromContext(ctx context.Context) (string, bool) { md, ok := metadata.FromIncomingContext(ctx) diff --git a/api/utils/grpc/interceptors/errors.go b/api/utils/grpc/interceptors/errors.go new file mode 100644 index 000000000000..d387c9adbc34 --- /dev/null +++ b/api/utils/grpc/interceptors/errors.go @@ -0,0 +1,87 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package interceptors + +import ( + "context" + + "github.com/gravitational/trace" + "github.com/gravitational/trace/trail" + "google.golang.org/grpc" +) + +// grpcServerStreamWrapper wraps around the embedded grpc.ServerStream +// and intercepts the RecvMsg and SendMsg method calls converting errors +// to the appropriate gRPC status error. +type grpcServerStreamWrapper struct { + grpc.ServerStream +} + +// SendMsg wraps around ServerStream.SendMsg and adds metrics reporting +func (s *grpcServerStreamWrapper) SendMsg(m interface{}) error { + return trace.Unwrap(trail.FromGRPC(s.ServerStream.SendMsg(m))) +} + +// RecvMsg wraps around ServerStream.RecvMsg and adds metrics reporting +func (s *grpcServerStreamWrapper) RecvMsg(m interface{}) error { + return trace.Unwrap(trail.FromGRPC(s.ServerStream.RecvMsg(m))) +} + +// grpcClientStreamWrapper wraps around the embedded grpc.ClientStream +// and intercepts the RecvMsg and SendMsg method calls converting errors +// to the appropriate gRPC status error. +type grpcClientStreamWrapper struct { + grpc.ClientStream +} + +// SendMsg wraps around ClientStream.SendMsg +func (s *grpcClientStreamWrapper) SendMsg(m interface{}) error { + return trace.Unwrap(trail.FromGRPC(s.ClientStream.SendMsg(m))) +} + +// RecvMsg wraps around ClientStream.RecvMsg +func (s *grpcClientStreamWrapper) RecvMsg(m interface{}) error { + return trace.Unwrap(trail.FromGRPC(s.ClientStream.RecvMsg(m))) +} + +// GRPCServerUnaryErrorInterceptor is a gRPC unary server interceptor that +// handles converting errors to the appropriate gRPC status error. +func GRPCServerUnaryErrorInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + resp, err := handler(ctx, req) + return resp, trace.Unwrap(trail.ToGRPC(err)) +} + +// GRPCClientUnaryErrorInterceptor is a gRPC unary client interceptor that +// handles converting errors to the appropriate grpc status error. +func GRPCClientUnaryErrorInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + return trace.Unwrap(trail.FromGRPC(invoker(ctx, method, req, reply, cc, opts...))) +} + +// GRPCServerStreamErrorInterceptor is a gRPC server stream interceptor that +// handles converting errors to the appropriate gRPC status error. +func GRPCServerStreamErrorInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + serverWrapper := &grpcServerStreamWrapper{ss} + return trace.Unwrap(trail.ToGRPC(handler(srv, serverWrapper))) +} + +// GRPCClientStreamErrorInterceptor is gRPC client stream interceptor that +// handles converting errors to the appropriate gRPC status error. +func GRPCClientStreamErrorInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + s, err := streamer(ctx, desc, cc, method, opts...) + if err != nil { + return nil, trace.Unwrap(trail.ToGRPC(err)) + } + return &grpcClientStreamWrapper{s}, nil +} diff --git a/api/utils/grpc/interceptors/errors_test.go b/api/utils/grpc/interceptors/errors_test.go new file mode 100644 index 000000000000..b3a9bfecd402 --- /dev/null +++ b/api/utils/grpc/interceptors/errors_test.go @@ -0,0 +1,103 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package interceptors + +import ( + "context" + "errors" + "io" + "net" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "github.com/gravitational/teleport/api/client/proto" +) + +// service is used to implement EchoServer +type service struct { + proto.UnimplementedAuthServiceServer +} + +func (s *service) Ping(ctx context.Context, req *proto.PingRequest) (*proto.PingResponse, error) { + return nil, trace.NotFound("not found") +} + +func (s *service) AddMFADevice(stream proto.AuthService_AddMFADeviceServer) error { + return trace.AlreadyExists("already exists") +} + +// TestGRPCErrorWrapping tests the error wrapping capability of the client +// and server unary and stream interceptors +func TestGRPCErrorWrapping(t *testing.T) { + t.Parallel() + + listener, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err) + + server := grpc.NewServer( + grpc.ChainUnaryInterceptor(GRPCServerUnaryErrorInterceptor), + grpc.ChainStreamInterceptor(GRPCServerStreamErrorInterceptor), + ) + proto.RegisterAuthServiceServer(server, &service{}) + go func() { + server.Serve(listener) + }() + defer server.Stop() + + conn, err := grpc.Dial( + listener.Addr().String(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithChainUnaryInterceptor(GRPCClientUnaryErrorInterceptor), + grpc.WithChainStreamInterceptor(GRPCClientStreamErrorInterceptor), + ) + require.NoError(t, err) + defer conn.Close() + + client := proto.NewAuthServiceClient(conn) + + t.Run("unary interceptor", func(t *testing.T) { + resp, err := client.Ping(context.Background(), &proto.PingRequest{}) + require.Nil(t, resp) + require.True(t, trace.IsNotFound(err)) + require.Equal(t, err.Error(), "not found") + _, ok := err.(*trace.TraceErr) + require.False(t, ok, "client error should not include traces originating in the middleware") + }) + + t.Run("stream interceptor", func(t *testing.T) { + stream, err := client.AddMFADevice(context.Background()) + require.NoError(t, err) + + sendErr := stream.Send(&proto.AddMFADeviceRequest{}) + + // io.EOF means the server closed the stream, which can + // happen depending in timing. In either case, it is + // still safe to recv from the stream and check for + // the already exists error. + if sendErr != nil && !errors.Is(sendErr, io.EOF) { + t.Fatalf("Unexpected error: %v", sendErr) + } + + _, err = stream.Recv() + require.True(t, trace.IsAlreadyExists(err)) + require.Equal(t, err.Error(), "already exists") + _, ok := err.(*trace.TraceErr) + require.False(t, ok, "client error should not include traces originating in the middleware") + }) +} diff --git a/api/utils/grpc/stream/stream.go b/api/utils/grpc/stream/stream.go index 54021755d273..a74f411b585f 100644 --- a/api/utils/grpc/stream/stream.go +++ b/api/utils/grpc/stream/stream.go @@ -22,7 +22,6 @@ import ( "time" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" ) // MaxChunkSize is the maximum number of bytes to send in a single data message. @@ -75,7 +74,7 @@ func (c *ReadWriter) Read(b []byte) (n int, err error) { return 0, io.EOF } if err != nil { - return 0, trace.ConnectionProblem(trail.FromGRPC(err), "failed to receive from source: %v", err) + return 0, trace.ConnectionProblem(trace.Wrap(err), "failed to receive from source: %v", err) } if data == nil { @@ -113,7 +112,7 @@ func (c *ReadWriter) Write(b []byte) (int, error) { } if err := c.source.Send(chunk); err != nil { - return sent, trace.ConnectionProblem(trail.FromGRPC(err), "failed to send on source: %v", err) + return sent, trace.ConnectionProblem(trace.Wrap(err), "failed to send on source: %v", err) } sent += len(chunk) diff --git a/constants.go b/constants.go index c73b53799dea..7060649a0caa 100644 --- a/constants.go +++ b/constants.go @@ -104,7 +104,7 @@ const ( // ComponentAuth is the cluster CA node (auth server API) ComponentAuth = "auth" - // ComponentGRPC is grpc server + // ComponentGRPC is gRPC server ComponentGRPC = "grpc" // ComponentMigrate is responsible for data migrations diff --git a/examples/resources/plugins/teleport-gitlab.toml b/examples/resources/plugins/teleport-gitlab.toml index efc2f72e82d9..780232503fde 100644 --- a/examples/resources/plugins/teleport-gitlab.toml +++ b/examples/resources/plugins/teleport-gitlab.toml @@ -1,8 +1,8 @@ # example teleport-gitlab configuration TOML file [teleport] -auth_server = "example.com:3025" # Teleport Auth Server GRPC API address -client_key = "/var/lib/teleport/plugins/gitlab/auth.key" # Teleport GRPC API client secret key -client_crt = "/var/lib/teleport/plugins/gitlab/auth.crt" # Teleport GRPC client certificate +auth_server = "example.com:3025" # Teleport Auth Server gRPC API address +client_key = "/var/lib/teleport/plugins/gitlab/auth.key" # Teleport gRPC API client secret key +client_crt = "/var/lib/teleport/plugins/gitlab/auth.crt" # Teleport gRPC client certificate root_cas = "/var/lib/teleport/plugins/gitlab/auth.cas" # Teleport cluster CA certs [db] diff --git a/go.mod b/go.mod index e60c148013da..85a3abaa2841 100644 --- a/go.mod +++ b/go.mod @@ -178,7 +178,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 google.golang.org/grpc v1.57.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 - google.golang.org/grpc/examples v0.0.0-20221010194801-c67245195065 google.golang.org/protobuf v1.31.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/dnaeon/go-vcr.v3 v3.1.2 diff --git a/go.sum b/go.sum index 5bbc8cdeb511..85bd331f7a14 100644 --- a/go.sum +++ b/go.sum @@ -2209,8 +2209,6 @@ google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/grpc/examples v0.0.0-20200723182653-9106c3fff523/go.mod h1:5j1uub0jRGhRiSghIlrThmBUgcgLXOVJQ/l1getT4uo= google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= -google.golang.org/grpc/examples v0.0.0-20221010194801-c67245195065 h1:dhjE21clLrAa6Yeigaw0Kxy0r02+IuNnyqTa+3TE0qg= -google.golang.org/grpc/examples v0.0.0-20221010194801-c67245195065/go.mod h1:gxndsbNG1n4TZcHGgsYEfVGnTxqfEdfiDv6/DADXX9o= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/integrations/access/common/app.go b/integrations/access/common/app.go index 100f066501d7..ffa1f1c9ad9a 100644 --- a/integrations/access/common/app.go +++ b/integrations/access/common/app.go @@ -34,7 +34,7 @@ import ( const ( // minServerVersion is the minimal teleport version the plugin supports. minServerVersion = "6.1.0-beta.1" - // grpcBackoffMaxDelay is a maximum time GRPC client waits before reconnection attempt. + // grpcBackoffMaxDelay is a maximum time gRPC client waits before reconnection attempt. grpcBackoffMaxDelay = time.Second * 2 // InitTimeout is used to bound execution time of health check and teleport version check. initTimeout = time.Second * 10 diff --git a/integrations/access/jira/app.go b/integrations/access/jira/app.go index 905af395802e..41ec690955ce 100644 --- a/integrations/access/jira/app.go +++ b/integrations/access/jira/app.go @@ -47,7 +47,7 @@ const ( minServerVersion = "6.1.0" // pluginName is used to tag PluginData and as a Delegator in Audit log. pluginName = "jira" - // grpcBackoffMaxDelay is a maximum time GRPC client waits before reconnection attempt. + // grpcBackoffMaxDelay is a maximum time gRPC client waits before reconnection attempt. grpcBackoffMaxDelay = time.Second * 2 // initTimeout is used to bound execution time of health check and teleport version check. initTimeout = time.Second * 10 diff --git a/integrations/access/jira/config.go b/integrations/access/jira/config.go index 3affceef7ad2..553f8be1c97f 100644 --- a/integrations/access/jira/config.go +++ b/integrations/access/jira/config.go @@ -38,7 +38,7 @@ type Config struct { Log logger.Config `toml:"log"` // Teleport is a handle to the client to use when communicating with - // the Teleport auth server. The Jira app will create a GRPC-based + // the Teleport auth server. The Jira app will create a gRPC-based // client on startup if this is not set. Client teleport.Client @@ -109,7 +109,7 @@ func (c *JiraConfig) CheckAndSetDefaults() error { } // LoadTLSConfig loads client crt/key files and root authorities, and -// generates a tls.Config suitable for use with a GRPC client. +// generates a tls.Config suitable for use with a gRPC client. func (c *Config) LoadTLSConfig() (*tls.Config, error) { var tc tls.Config clientCert, err := tls.LoadX509KeyPair(c.Teleport.ClientCrt, c.Teleport.ClientKey) diff --git a/integrations/access/opsgenie/app.go b/integrations/access/opsgenie/app.go index 7395a7dbba3d..2ce395d1a96f 100644 --- a/integrations/access/opsgenie/app.go +++ b/integrations/access/opsgenie/app.go @@ -45,7 +45,7 @@ const ( pluginName = "opsgenie" // minServerVersion is the minimal teleport version the plugin supports. minServerVersion = "6.1.0" - // grpcBackoffMaxDelay is a maximum time GRPC client waits before reconnection attempt. + // grpcBackoffMaxDelay is a maximum time gRPC client waits before reconnection attempt. grpcBackoffMaxDelay = time.Second * 2 // initTimeout is used to bound execution time of health check and teleport version check. initTimeout = time.Second * 10 diff --git a/integrations/access/pagerduty/app.go b/integrations/access/pagerduty/app.go index 2f7a59a919e0..7dbb1f3e79ac 100644 --- a/integrations/access/pagerduty/app.go +++ b/integrations/access/pagerduty/app.go @@ -45,7 +45,7 @@ const ( minServerVersion = "6.1.0" // pluginName is used to tag PluginData and as a Delegator in Audit log. pluginName = "pagerduty" - // grpcBackoffMaxDelay is a maximum time GRPC client waits before reconnection attempt. + // grpcBackoffMaxDelay is a maximum time gRPC client waits before reconnection attempt. grpcBackoffMaxDelay = time.Second * 2 // initTimeout is used to bound execution time of health check and teleport version check. initTimeout = time.Second * 10 diff --git a/integrations/access/pagerduty/config.go b/integrations/access/pagerduty/config.go index 7826258f1c17..4138fef903bd 100644 --- a/integrations/access/pagerduty/config.go +++ b/integrations/access/pagerduty/config.go @@ -31,7 +31,7 @@ type Config struct { Log logger.Config `toml:"log"` // Teleport is a handle to the client to use when communicating with - // the Teleport auth server. The PagerDuty app will create a GRPC- + // the Teleport auth server. The PagerDuty app will create a gRPC- // based client on startup if this is not set. Client teleport.Client diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index b1803acb07a0..5203a0fdf04d 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -108,7 +108,7 @@ var ( ) ) -// GRPCServer is GPRC Auth Server API +// GRPCServer is gRPC Auth Server API type GRPCServer struct { auditlogpb.UnimplementedAuditLogServiceServer *logrus.Entry @@ -1900,7 +1900,7 @@ func (g *GRPCServer) DeleteAllKubernetesServers(ctx context.Context, req *authpb return &emptypb.Empty{}, nil } -// maybeDowngradeRole tests the client version passed through the GRPC metadata, +// maybeDowngradeRole tests the client version passed through the gRPC metadata, // and if the client version is unknown or less than the minimum supported // version for some features of the role returns a shallow copy of the given // role downgraded for compatibility with the older version. @@ -1972,7 +1972,7 @@ func maybeDowngradeRoleLabelExpressions(ctx context.Context, role *types.RoleV6, var minSupportedRoleV7Version = semver.New(utils.VersionBeforeAlpha("14.0.0")) -// maybeDowngradeRoleToV6 tests the client version passed through the GRPC metadata, and +// maybeDowngradeRoleToV6 tests the client version passed through the gRPC metadata, and // if the client version is less than the minimum supported version // for V7 roles returns a shallow copy of the given role downgraded to V6, If // the passed in role is already V6, it is returned unmodified. @@ -2167,11 +2167,11 @@ func (g *GRPCServer) DeleteRole(ctx context.Context, req *authpb.DeleteRoleReque // and updates the users presence for a given session. // // This function bypasses the `ServerWithRoles` RBAC layer. This is not -// usually how the GRPC layer accesses the underlying auth server API's but it's done +// usually how the gRPC layer accesses the underlying auth server API's but it's done // here to avoid bloating the ClientI interface with special logic that isn't designed to be touched // by anyone external to this process. This is not the norm and caution should be taken // when looking at or modifying this function. This is the same approach taken by other MFA -// related GRPC API endpoints. +// related gRPC API endpoints. func doMFAPresenceChallenge(ctx context.Context, actx *grpcContext, stream authpb.AuthService_MaintainSessionPresenceServer, challengeReq *authpb.PresenceMFAChallengeRequest) error { user := actx.User.GetName() @@ -5202,11 +5202,11 @@ func (g *GRPCServer) GetBackend() backend.Backend { return g.AuthServer.bk } -// GRPCServerConfig specifies GRPC server configuration +// GRPCServerConfig specifies gRPC server configuration type GRPCServerConfig struct { - // APIConfig is GRPC server API configuration + // APIConfig is gRPC server API configuration APIConfig - // TLS is GRPC server config + // TLS is gRPC server config TLS *tls.Config // Middleware is the request TLS client authenticator Middleware *Middleware @@ -5233,7 +5233,7 @@ func (cfg *GRPCServerConfig) CheckAndSetDefaults() error { return nil } -// NewGRPCServer returns a new instance of GRPC server +// NewGRPCServer returns a new instance of gRPC server func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) { err := metrics.RegisterPrometheusCollectors(heartbeatConnectionsReceived, watcherEventsEmitted, watcherEventSizes, connectedResources) if err != nil { @@ -5243,7 +5243,7 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) { if err := cfg.CheckAndSetDefaults(); err != nil { return nil, trace.Wrap(err) } - log.Debugf("GRPC(SERVER): keep alive %v count: %v.", cfg.KeepAlivePeriod, cfg.KeepAliveCount) + log.Debugf("gRPC(SERVER): keep alive %v count: %v.", cfg.KeepAlivePeriod, cfg.KeepAliveCount) // httplib.TLSCreds are explicitly used instead of credentials.NewTLS because the latter // modifies the tls.Config.NextProtos which causes problems due to multiplexing on the auth diff --git a/lib/auth/grpcserver_test.go b/lib/auth/grpcserver_test.go index 6629f20971d8..96fc29335309 100644 --- a/lib/auth/grpcserver_test.go +++ b/lib/auth/grpcserver_test.go @@ -43,8 +43,6 @@ import ( otlpcommonv1 "go.opentelemetry.io/proto/otlp/common/v1" otlpresourcev1 "go.opentelemetry.io/proto/otlp/resource/v1" otlptracev1 "go.opentelemetry.io/proto/otlp/trace/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/emptypb" @@ -215,7 +213,7 @@ func TestMFADeviceManagement(t *testing.T) { }, checkAuthErr: func(t require.TestingT, err error, i ...interface{}) { require.Error(t, err) - require.Equal(t, codes.PermissionDenied, status.Code(err)) + require.True(t, trace.IsAccessDenied(err)) }, }, }, @@ -246,7 +244,7 @@ func TestMFADeviceManagement(t *testing.T) { }, checkRegisterErr: func(t require.TestingT, err error, i ...interface{}) { require.Error(t, err) - require.Equal(t, codes.InvalidArgument, status.Code(err)) + require.True(t, trace.IsBadParameter(err)) }, }, }, diff --git a/lib/auth/http_client.go b/lib/auth/http_client.go index 8eeac3bb141b..3a74c7e59380 100644 --- a/lib/auth/http_client.go +++ b/lib/auth/http_client.go @@ -89,7 +89,7 @@ func (c *HTTPClientConfig) CheckAndSetDefaults() error { // Set the next protocol. This is needed due to the Auth Server using a // multiplexer for protocol detection. Unless next protocol is specified // it will attempt to upgrade to HTTP2 and at that point there is no way - // to distinguish between HTTP2/JSON or GPRC. + // to distinguish between HTTP2/JSON or gRPC. c.TLS.NextProtos = []string{teleport.HTTPNextProtoTLS} // Configure ALPN SNI direct dial TLS routing information used by ALPN SNI proxy in order to diff --git a/lib/auth/keystore/gcp_kms_test.go b/lib/auth/keystore/gcp_kms_test.go index c9e052f9f050..92799e89fb22 100644 --- a/lib/auth/keystore/gcp_kms_test.go +++ b/lib/auth/keystore/gcp_kms_test.go @@ -40,6 +40,7 @@ import ( "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" "github.com/gravitational/teleport/lib/auth/keystore/internal/faketime" "github.com/gravitational/teleport/lib/auth/testauthority" "github.com/gravitational/teleport/lib/jwt" @@ -287,8 +288,8 @@ func (f *fakeGCPKMSServer) activateAllKeys() { func newTestGRPCServer() *grpc.Server { // Set up some helpful interceptors so that we return compliant error types. return grpc.NewServer( - grpc.UnaryInterceptor(utils.GRPCServerUnaryErrorInterceptor), - grpc.StreamInterceptor(utils.GRPCServerStreamErrorInterceptor), + grpc.UnaryInterceptor(interceptors.GRPCServerUnaryErrorInterceptor), + grpc.StreamInterceptor(interceptors.GRPCServerStreamErrorInterceptor), ) } diff --git a/lib/auth/middleware.go b/lib/auth/middleware.go index ec8fd6fe325a..8046ebb6522d 100644 --- a/lib/auth/middleware.go +++ b/lib/auth/middleware.go @@ -42,6 +42,7 @@ import ( apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" "github.com/gravitational/teleport/lib/authz" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/httplib" @@ -148,7 +149,7 @@ func NewTLSServer(cfg TLSServerConfig) (*TLSServer, error) { return nil, trace.Wrap(err) } - // sets up grpc metrics interceptor + // sets up gRPC metrics interceptor grpcMetrics := metrics.CreateGRPCServerMetrics(cfg.Metrics.GRPCServerLatency, prometheus.Labels{teleport.TagServer: "teleport-auth"}) err = metrics.RegisterPrometheusCollectors(grpcMetrics) if err != nil { @@ -263,7 +264,7 @@ func (t *TLSServer) Shutdown(ctx context.Context) error { return trace.NewAggregate(errors...) } -// Serve starts GRPC and HTTP1.1 services on the mux listener +// Serve starts gRPC and HTTP1.1 services on the mux listener func (t *TLSServer) Serve() error { errC := make(chan error, 2) go func() { @@ -353,7 +354,7 @@ type Middleware struct { AcceptedUsage []string // Limiter is a rate and connection limiter Limiter *limiter.Limiter - // GRPCMetrics is the configured grpc metrics for the interceptors + // GRPCMetrics is the configured gRPC metrics for the interceptors GRPCMetrics *om.ServerMetrics // EnableCredentialsForwarding allows the middleware to receive impersonation // identity from the client if it presents a valid proxy certificate. @@ -478,7 +479,7 @@ func (a *Middleware) UnaryInterceptors() []grpc.UnaryServerInterceptor { } return append(is, - utils.GRPCServerUnaryErrorInterceptor, + interceptors.GRPCServerUnaryErrorInterceptor, a.Limiter.UnaryServerInterceptorWithCustomRate(getCustomRate), a.withAuthenticatedUserUnaryInterceptor, ) @@ -495,7 +496,7 @@ func (a *Middleware) StreamInterceptors() []grpc.StreamServerInterceptor { } return append(is, - utils.GRPCServerStreamErrorInterceptor, + interceptors.GRPCServerStreamErrorInterceptor, a.Limiter.StreamServerInterceptor, a.withAuthenticatedUserStreamInterceptor, ) diff --git a/lib/backend/firestore/README.md b/lib/backend/firestore/README.md index 1dea357fb65c..6b1f031d8975 100644 --- a/lib/backend/firestore/README.md +++ b/lib/backend/firestore/README.md @@ -71,7 +71,7 @@ There are three authentication/authorization modes available; Google Application Default Credentials for authentication. This only works in cases where Teleport is installed on GCE instances and have service accounts with IAM role/profile associations authorizing that GCE instance to use Firestore. -2. With `endpoint` defined, Firestore will create clients no auth, GRPC in-secure, clients pointed +2. With `endpoint` defined, Firestore will create clients no auth, gRPC in-secure, clients pointed at the specified endpoint. **This is only used for tests, see `Tests` section below.** 3. With `credentialsPath` defined, Firestore will create clients authenticating against live systems with the Service Account bound to the JSON key file referenced in the option. diff --git a/lib/backend/firestore/firestorebk.go b/lib/backend/firestore/firestorebk.go index 8fce65ab248e..e20bcb065473 100644 --- a/lib/backend/firestore/firestorebk.go +++ b/lib/backend/firestore/firestorebk.go @@ -820,7 +820,7 @@ func (b *Backend) deleteDocuments(docs []*firestore.DocumentSnapshot) error { return trace.NewAggregate(errs...) } -// ConvertGRPCError converts GRPC errors +// ConvertGRPCError converts gRPC errors func ConvertGRPCError(err error, args ...interface{}) error { if err == nil { return nil diff --git a/lib/client/api.go b/lib/client/api.go index e365dc2e9488..57ca88c20fd6 100644 --- a/lib/client/api.go +++ b/lib/client/api.go @@ -61,6 +61,7 @@ import ( "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" apiutils "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/auth/native" @@ -2827,8 +2828,8 @@ func (tc *TeleportClient) ConnectToCluster(ctx context.Context) (*ClusterClient, TLSRoutingEnabled: tc.TLSRoutingEnabled, TLSConfig: tlsConfig, DialOpts: tc.Config.DialOpts, - UnaryInterceptors: []grpc.UnaryClientInterceptor{utils.GRPCClientUnaryErrorInterceptor}, - StreamInterceptors: []grpc.StreamClientInterceptor{utils.GRPCClientStreamErrorInterceptor}, + UnaryInterceptors: []grpc.UnaryClientInterceptor{interceptors.GRPCClientUnaryErrorInterceptor}, + StreamInterceptors: []grpc.StreamClientInterceptor{interceptors.GRPCClientStreamErrorInterceptor}, SSHConfig: cfg.ClientConfig, ALPNConnUpgradeRequired: tc.TLSRoutingConnUpgradeRequired, InsecureSkipVerify: tc.InsecureSkipVerify, diff --git a/lib/client/identityfile/identity.go b/lib/client/identityfile/identity.go index d390464a00f8..bf7021130663 100644 --- a/lib/client/identityfile/identity.go +++ b/lib/client/identityfile/identity.go @@ -58,7 +58,7 @@ const ( // two different files (in the same directory) FormatOpenSSH Format = "openssh" - // FormatTLS is a standard TLS format used by common TLS clients (e.g. GRPC) where + // FormatTLS is a standard TLS format used by common TLS clients (e.g. gRPC) where // certificate and key are stored in separate files. FormatTLS Format = "tls" diff --git a/lib/config/fileconf.go b/lib/config/fileconf.go index d591a4fddd76..324aca8f1703 100644 --- a/lib/config/fileconf.go +++ b/lib/config/fileconf.go @@ -2419,10 +2419,10 @@ type Metrics struct { // mTLS will be enabled for the service if both 'keypairs' and 'ca_certs' fields are set. CACerts []string `yaml:"ca_certs,omitempty"` - // GRPCServerLatency enables histogram metrics for each grpc endpoint on the auth server + // GRPCServerLatency enables histogram metrics for each gRPC endpoint on the auth server GRPCServerLatency bool `yaml:"grpc_server_latency,omitempty"` - // GRPCServerLatency enables histogram metrics for each grpc endpoint on the auth server + // GRPCServerLatency enables histogram metrics for each gRPC endpoint on the auth server GRPCClientLatency bool `yaml:"grpc_client_latency,omitempty"` } diff --git a/lib/devicetrust/testenv/testenv.go b/lib/devicetrust/testenv/testenv.go index 7d970c5a0032..814ec3f807f1 100644 --- a/lib/devicetrust/testenv/testenv.go +++ b/lib/devicetrust/testenv/testenv.go @@ -25,7 +25,7 @@ import ( "google.golang.org/grpc/test/bufconn" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" - "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" ) // Opt is a creation option for [E] @@ -94,8 +94,8 @@ func New(opts ...Opt) (*E, error) { s := grpc.NewServer( // Options below are similar to auth.GRPCServer. - grpc.StreamInterceptor(utils.GRPCServerStreamErrorInterceptor), - grpc.UnaryInterceptor(utils.GRPCServerUnaryErrorInterceptor), + grpc.StreamInterceptor(interceptors.GRPCServerStreamErrorInterceptor), + grpc.UnaryInterceptor(interceptors.GRPCServerUnaryErrorInterceptor), ) e.closers = append(e.closers, func() error { s.GracefulStop() @@ -121,8 +121,8 @@ func New(opts ...Opt) (*E, error) { return lis.DialContext(ctx) }), grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithStreamInterceptor(utils.GRPCClientStreamErrorInterceptor), - grpc.WithUnaryInterceptor(utils.GRPCClientUnaryErrorInterceptor), + grpc.WithStreamInterceptor(interceptors.GRPCClientStreamErrorInterceptor), + grpc.WithUnaryInterceptor(interceptors.GRPCClientUnaryErrorInterceptor), ) if err != nil { return nil, err diff --git a/lib/events/firestoreevents/README.md b/lib/events/firestoreevents/README.md index e5afdf2522e8..930d2e65dac8 100644 --- a/lib/events/firestoreevents/README.md +++ b/lib/events/firestoreevents/README.md @@ -56,7 +56,7 @@ There are three authentication/authorization modes available; Google Application Default Credentials for authentication. This only works in cases where Teleport is installed on GCE instances and have service accounts with IAM role/profile associations authorizing that GCE instance to use Firestore. -2. With `endpoint` defined, Firestore will create clients no auth, GRPC in-secure, clients pointed +2. With `endpoint` defined, Firestore will create clients no auth, gRPC in-secure, clients pointed at the specified endpoint. **This is only used for tests, see `Tests` section below.** 3. With `credentialsPath` defined, Firestore will create clients authenticating against live systems with the Service Account bound to the JSON key file referenced in the option. diff --git a/lib/joinserver/joinserver_test.go b/lib/joinserver/joinserver_test.go index b5ef58b83b7b..18dd20cd12f5 100644 --- a/lib/joinserver/joinserver_test.go +++ b/lib/joinserver/joinserver_test.go @@ -33,7 +33,7 @@ import ( "github.com/gravitational/teleport/api/client" "github.com/gravitational/teleport/api/client/proto" - "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" ) type mockJoinServiceClient struct { @@ -73,8 +73,8 @@ func ConnectionCountingStreamInterceptor(count *atomic.Int32) grpc.StreamServerI func newGRPCServer(t *testing.T, opts ...grpc.ServerOption) (*grpc.Server, *bufconn.Listener) { lis := bufconn.Listen(1024) opts = append(opts, - grpc.ChainUnaryInterceptor(utils.GRPCServerUnaryErrorInterceptor), - grpc.ChainStreamInterceptor(utils.GRPCServerStreamErrorInterceptor), + grpc.ChainUnaryInterceptor(interceptors.GRPCServerUnaryErrorInterceptor), + grpc.ChainStreamInterceptor(interceptors.GRPCServerStreamErrorInterceptor), ) s := grpc.NewServer(opts...) return s, lis diff --git a/lib/observability/metrics/prometheus.go b/lib/observability/metrics/prometheus.go index 6cb78135d002..06c20a280ab6 100644 --- a/lib/observability/metrics/prometheus.go +++ b/lib/observability/metrics/prometheus.go @@ -60,7 +60,7 @@ func BuildCollector() prometheus.Collector { ) } -// CreateGRPCServerMetrics creates server grpc metrics configuration that is to be registered and used by the caller +// CreateGRPCServerMetrics creates server gRPC metrics configuration that is to be registered and used by the caller // in an openmetrics unary and/or stream interceptor func CreateGRPCServerMetrics(latencyEnabled bool, labels prometheus.Labels) *om.ServerMetrics { serverOpts := []om.ServerMetricsOption{om.WithServerCounterOptions(om.WithConstLabels(labels))} @@ -71,7 +71,7 @@ func CreateGRPCServerMetrics(latencyEnabled bool, labels prometheus.Labels) *om. return om.NewServerMetrics(serverOpts...) } -// CreateGRPCClientMetrics creates client grpc metrics configuration that is to be registered and used by the caller +// CreateGRPCClientMetrics creates client gRPC metrics configuration that is to be registered and used by the caller // in an openmetrics unary and/or stream interceptor func CreateGRPCClientMetrics(latencyEnabled bool, labels prometheus.Labels) *om.ClientMetrics { clientOpts := []om.ClientMetricsOption{om.WithClientCounterOptions(om.WithConstLabels(labels))} diff --git a/lib/proxy/peer/client.go b/lib/proxy/peer/client.go index 57c79e9a8775..b5d1f321a9b4 100644 --- a/lib/proxy/peer/client.go +++ b/lib/proxy/peer/client.go @@ -34,11 +34,11 @@ import ( clientapi "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/metadata" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" streamutils "github.com/gravitational/teleport/api/utils/grpc/stream" "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/services" - "github.com/gravitational/teleport/lib/utils" ) // ClientConfig configures a Client instance. @@ -617,7 +617,7 @@ func (c *Client) connect(peerID string, peerAddr string) (*clientConn, error) { peerAddr, grpc.WithTransportCredentials(newClientCredentials(expectedPeer, peerAddr, c.config.Log, credentials.NewTLS(tlsConfig))), grpc.WithStatsHandler(newStatsHandler(c.reporter)), - grpc.WithChainStreamInterceptor(metadata.StreamClientInterceptor, utils.GRPCClientStreamErrorInterceptor, streamCounterInterceptor(wg)), + grpc.WithChainStreamInterceptor(metadata.StreamClientInterceptor, interceptors.GRPCClientStreamErrorInterceptor, streamCounterInterceptor(wg)), grpc.WithKeepaliveParams(keepalive.ClientParameters{ Time: peerKeepAlive, Timeout: peerTimeout, diff --git a/lib/proxy/peer/interceptor.go b/lib/proxy/peer/interceptor.go index 19f103b9b8aa..af9392e6841f 100644 --- a/lib/proxy/peer/interceptor.go +++ b/lib/proxy/peer/interceptor.go @@ -59,9 +59,9 @@ func (s *streamWrapper) decreaseCounter() { }) } -// streamCounterInterceptor is GPRC client stream interceptor that +// streamCounterInterceptor is gRPC client stream interceptor that // counts the number of current open streams for the purpose of -// gracefully shutdown a draining grpc client. +// gracefully shutdown a draining gRPC client. func streamCounterInterceptor(wg *sync.WaitGroup) grpc.StreamClientInterceptor { return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { s, err := streamer(ctx, desc, cc, method, opts...) diff --git a/lib/service/service.go b/lib/service/service.go index c2fd02cbe6e8..6527ce7c0ef4 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -68,6 +68,7 @@ import ( apievents "github.com/gravitational/teleport/api/types/events" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/aws" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" "github.com/gravitational/teleport/api/utils/retryutils" "github.com/gravitational/teleport/lib" "github.com/gravitational/teleport/lib/agentless" @@ -102,7 +103,7 @@ import ( "github.com/gravitational/teleport/lib/httplib" "github.com/gravitational/teleport/lib/inventory" "github.com/gravitational/teleport/lib/joinserver" - kubegprc "github.com/gravitational/teleport/lib/kube/grpc" + kubegrpc "github.com/gravitational/teleport/lib/kube/grpc" kubeproxy "github.com/gravitational/teleport/lib/kube/proxy" "github.com/gravitational/teleport/lib/labels" "github.com/gravitational/teleport/lib/limiter" @@ -2049,7 +2050,7 @@ func (process *TeleportProcess) initAuthService() error { ctx := payloadContext(payload, log) log.Info("Shutting down immediately (auth service does not currently support graceful shutdown).") // NOTE: Graceful shutdown of auth.TLSServer is disabled right now, because we don't - // have a good model for performing it. In particular, watchers and other GRPC streams + // have a good model for performing it. In particular, watchers and other gRPC streams // are a problem. Even if we distinguish between user-created and server-created streams // (as is done with ssh connections), we don't have a way to distinguish "service accounts" // such as access workflow plugins from normal users. Without this, a graceful shutdown @@ -4181,11 +4182,11 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { sshGRPCServer := grpc.NewServer( grpc.ChainUnaryInterceptor( - utils.GRPCServerUnaryErrorInterceptor, + interceptors.GRPCServerUnaryErrorInterceptor, otelgrpc.UnaryServerInterceptor(), ), grpc.ChainStreamInterceptor( - utils.GRPCServerStreamErrorInterceptor, + interceptors.GRPCServerStreamErrorInterceptor, otelgrpc.StreamServerInterceptor(), ), grpc.Creds(creds), @@ -5806,11 +5807,11 @@ func (process *TeleportProcess) initPublicGRPCServer( ) *grpc.Server { server := grpc.NewServer( grpc.ChainUnaryInterceptor( - utils.GRPCServerUnaryErrorInterceptor, + interceptors.GRPCServerUnaryErrorInterceptor, limiter.UnaryServerInterceptor(), ), grpc.ChainStreamInterceptor( - utils.GRPCServerStreamErrorInterceptor, + interceptors.GRPCServerStreamErrorInterceptor, limiter.StreamServerInterceptor, ), grpc.KeepaliveParams(keepalive.ServerParameters{ @@ -5891,7 +5892,7 @@ func (process *TeleportProcess) initSecureGRPCServer(cfg initSecureGRPCServerCfg grpc.Creds(creds), ) - kubeServer, err := kubegprc.New(kubegprc.Config{ + kubeServer, err := kubegrpc.New(kubegrpc.Config{ Signer: cfg.conn.Client, AccessPoint: cfg.accessPoint, Authz: authorizer, diff --git a/lib/service/service_test.go b/lib/service/service_test.go index 6125a361b4ff..5a329f243193 100644 --- a/lib/service/service_test.go +++ b/lib/service/service_test.go @@ -1147,8 +1147,8 @@ func TestProxyGRPCServers(t *testing.T) { }) // Insecure gRPC server. - insecureGPRC := process.initPublicGRPCServer(limiter, testConnector, insecureListener) - t.Cleanup(insecureGPRC.GracefulStop) + insecureGRPC := process.initPublicGRPCServer(limiter, testConnector, insecureListener) + t.Cleanup(insecureGRPC.GracefulStop) proxyLockWatcher, err := services.NewLockWatcher(context.Background(), services.LockWatcherConfig{ ResourceWatcherConfig: services.ResourceWatcherConfig{ @@ -1174,7 +1174,7 @@ func TestProxyGRPCServers(t *testing.T) { // Start the gRPC servers. go func() { - errC <- trace.Wrap(insecureGPRC.Serve(insecureListener)) + errC <- trace.Wrap(insecureGRPC.Serve(insecureListener)) }() go func() { errC <- secureGRPC.Serve(secureListener) diff --git a/lib/services/suite/suite.go b/lib/services/suite/suite.go index 721e155d68a6..64144a8b7215 100644 --- a/lib/services/suite/suite.go +++ b/lib/services/suite/suite.go @@ -155,7 +155,7 @@ func NewTestCAWithConfig(config TestCAConfig) *types.CertAuthorityV2 { // ServicesTestSuite is an acceptance test suite // for services. It is used for local implementations and implementations -// using GRPC to guarantee consistency between local and remote services +// using gRPC to guarantee consistency between local and remote services type ServicesTestSuite struct { Access services.Access CAS services.Trust diff --git a/lib/srv/transport/transportv1/transport_test.go b/lib/srv/transport/transportv1/transport_test.go index 91d1d24c0b4a..5a74f7182ebc 100644 --- a/lib/srv/transport/transportv1/transport_test.go +++ b/lib/srv/transport/transportv1/transport_test.go @@ -40,6 +40,7 @@ import ( "google.golang.org/grpc/test/bufconn" transportv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/transport/v1" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" streamutils "github.com/gravitational/teleport/api/utils/grpc/stream" "github.com/gravitational/teleport/lib/agentless" "github.com/gravitational/teleport/lib/authz" @@ -172,8 +173,8 @@ func newServer(t *testing.T, cfg ServerConfig) testPack { }) s := grpc.NewServer( - grpc.StreamInterceptor(utils.GRPCServerStreamErrorInterceptor), - grpc.UnaryInterceptor(utils.GRPCServerUnaryErrorInterceptor), + grpc.StreamInterceptor(interceptors.GRPCServerStreamErrorInterceptor), + grpc.UnaryInterceptor(interceptors.GRPCServerUnaryErrorInterceptor), ) t.Cleanup(func() { s.GracefulStop() @@ -205,8 +206,8 @@ func newServer(t *testing.T, cfg ServerConfig) testPack { }, err }), grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithStreamInterceptor(utils.GRPCClientStreamErrorInterceptor), - grpc.WithUnaryInterceptor(utils.GRPCClientUnaryErrorInterceptor), + grpc.WithStreamInterceptor(interceptors.GRPCClientStreamErrorInterceptor), + grpc.WithUnaryInterceptor(interceptors.GRPCClientUnaryErrorInterceptor), ) require.NoError(t, err) t.Cleanup(func() { diff --git a/lib/teleterm/apiserver/middleware.go b/lib/teleterm/apiserver/middleware.go index bd740ec768aa..f65337e7254a 100644 --- a/lib/teleterm/apiserver/middleware.go +++ b/lib/teleterm/apiserver/middleware.go @@ -25,7 +25,7 @@ import ( "google.golang.org/grpc" ) -// withErrorHandling is GRPC middleware that maps internal errors to proper GRPC error codes +// withErrorHandling is gRPC middleware that maps internal errors to proper gRPC error codes func withErrorHandling(log logrus.FieldLogger) grpc.UnaryServerInterceptor { return func( ctx context.Context, diff --git a/lib/utils/grpc.go b/lib/utils/grpc.go index 2593bf39d718..2a57e2b9f366 100644 --- a/lib/utils/grpc.go +++ b/lib/utils/grpc.go @@ -20,73 +20,18 @@ import ( "context" "github.com/gravitational/trace" - "github.com/gravitational/trace/trail" "google.golang.org/grpc" -) - -// grpcServerStreamWrapper wraps around the embedded grpc.ServerStream -// and intercepts the RecvMsg and SendMsg method calls converting errors to the -// appropriate grpc status error. -type grpcServerStreamWrapper struct { - grpc.ServerStream -} - -// SendMsg wraps around ServerStream.SendMsg and adds metrics reporting -func (s *grpcServerStreamWrapper) SendMsg(m interface{}) error { - return trail.FromGRPC(s.ServerStream.SendMsg(m)) -} - -// RecvMsg wraps around ServerStream.RecvMsg and adds metrics reporting -func (s *grpcServerStreamWrapper) RecvMsg(m interface{}) error { - return trail.FromGRPC(s.ServerStream.RecvMsg(m)) -} - -// grpcClientStreamWrapper wraps around the embedded grpc.ClientStream -// and intercepts the RecvMsg and SendMsg method calls converting errors to the -// appropriate grpc status error. -type grpcClientStreamWrapper struct { - grpc.ClientStream -} - -// SendMsg wraps around ClientStream.SendMsg -func (s *grpcClientStreamWrapper) SendMsg(m interface{}) error { - return trail.FromGRPC(s.ClientStream.SendMsg(m)) -} -// RecvMsg wraps around ClientStream.RecvMsg -func (s *grpcClientStreamWrapper) RecvMsg(m interface{}) error { - return trail.FromGRPC(s.ClientStream.RecvMsg(m)) -} - -// GRPCServerUnaryErrorInterceptor is a GPRC unary server interceptor that -// handles converting errors to the appropriate grpc status error. -func GRPCServerUnaryErrorInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - resp, err := handler(ctx, req) - return resp, trail.ToGRPC(err) -} - -// GRPCClientUnaryErrorInterceptor is a GPRC unary client interceptor that -// handles converting errors to the appropriate grpc status error. -func GRPCClientUnaryErrorInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - return trail.FromGRPC(invoker(ctx, method, req, reply, cc, opts...)) -} - -// GRPCServerStreamErrorInterceptor is a GPRC server stream interceptor that -// handles converting errors to the appropriate grpc status error. -func GRPCServerStreamErrorInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - serverWrapper := &grpcServerStreamWrapper{ss} - return trail.ToGRPC(handler(srv, serverWrapper)) -} + "github.com/gravitational/teleport/api/utils/grpc/interceptors" +) -// GRPCClientStreamErrorInterceptor is GPRC client stream interceptor that -// handles converting errors to the appropriate grpc status error. -func GRPCClientStreamErrorInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { - s, err := streamer(ctx, desc, cc, method, opts...) - if err != nil { - return nil, trail.ToGRPC(err) - } - return &grpcClientStreamWrapper{s}, nil -} +// TODO(Joerger): Remove these aliases once /e no longer depends on them. +var ( + GRPCServerUnaryErrorInterceptor = interceptors.GRPCServerUnaryErrorInterceptor + GRPCClientUnaryErrorInterceptor = interceptors.GRPCClientUnaryErrorInterceptor + GRPCServerStreamErrorInterceptor = interceptors.GRPCServerStreamErrorInterceptor + GRPCClientStreamErrorInterceptor = interceptors.GRPCClientStreamErrorInterceptor +) // NewGRPCDummyClientConnection returns an implementation of grpc.ClientConnInterface // that always responds with "not implemented" error with the given error message. diff --git a/lib/utils/grpc_test.go b/lib/utils/grpc_test.go deleted file mode 100644 index 9af1c32eef18..000000000000 --- a/lib/utils/grpc_test.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2022 Gravitational, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package utils - -import ( - "context" - "errors" - "io" - "net" - "testing" - - "github.com/gravitational/trace" - "github.com/stretchr/testify/require" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - pb "google.golang.org/grpc/examples/features/proto/echo" -) - -// service is used to implement EchoServer -type service struct { - pb.UnimplementedEchoServer -} - -func (s *service) UnaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { - return nil, trace.NotFound("not found") -} - -func (s *service) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { - return trace.AlreadyExists("already exists") -} - -// TestGRPCErrorWrapping tests the error wrapping capability of the client -// and server unary and stream interceptors -func TestGRPCErrorWrapping(t *testing.T) { - t.Parallel() - - listener, err := net.Listen("tcp", "localhost:0") - require.NoError(t, err) - - server := grpc.NewServer( - grpc.ChainUnaryInterceptor(GRPCServerUnaryErrorInterceptor), - grpc.ChainStreamInterceptor(GRPCServerStreamErrorInterceptor), - ) - pb.RegisterEchoServer(server, &service{}) - go func() { - server.Serve(listener) - }() - defer server.Stop() - - conn, err := grpc.Dial( - listener.Addr().String(), - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithChainUnaryInterceptor(GRPCClientUnaryErrorInterceptor), - grpc.WithChainStreamInterceptor(GRPCClientStreamErrorInterceptor), - ) - require.NoError(t, err) - defer conn.Close() - - // test unary interceptor - client := pb.NewEchoClient(conn) - resp, err := client.UnaryEcho(context.Background(), &pb.EchoRequest{Message: "Hi!"}) - require.Nil(t, resp) - require.True(t, trace.IsNotFound(err)) - require.Equal(t, err.Error(), "not found") - - // test stream interceptor - stream, err := client.BidirectionalStreamingEcho(context.Background()) - require.NoError(t, err) - - sendErr := stream.Send(&pb.EchoRequest{Message: "Hi!"}) - - // io.EOF means the server closed the stream, which can - // happen depending in timing. In either case, it is - // still safe to recv from the stream and check for - // the already exists error. - if sendErr != nil && !errors.Is(sendErr, io.EOF) { - require.FailNowf(t, "unexpected error", "%v", sendErr) - } - - _, err = stream.Recv() - require.True(t, trace.IsAlreadyExists(err)) - require.Equal(t, err.Error(), "already exists") -} diff --git a/lib/utils/tls.go b/lib/utils/tls.go index 0048cc522946..48cbad502697 100644 --- a/lib/utils/tls.go +++ b/lib/utils/tls.go @@ -138,7 +138,7 @@ const ( // secrecy (ECDHE). // // Note that TLS_RSA_WITH_AES_128_GCM_SHA{256,384} have been dropped due to -// being banned by HTTP2 which breaks GRPC clients. For more information see: +// being banned by HTTP2 which breaks gRPC clients. For more information see: // https://tools.ietf.org/html/rfc7540#appendix-A. These two can still be // manually added if needed. func DefaultCipherSuites() []uint16 { diff --git a/lib/web/apiserver_test.go b/lib/web/apiserver_test.go index 28ad8ff54acb..6351a4d82cc7 100644 --- a/lib/web/apiserver_test.go +++ b/lib/web/apiserver_test.go @@ -90,6 +90,7 @@ import ( "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" apiutils "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/api/utils/grpc/interceptors" "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/lib" "github.com/gravitational/teleport/lib/agentless" @@ -4165,7 +4166,7 @@ func TestClusterKubePodsGet(t *testing.T) { proxy := env.proxies[0] listener, err := net.Listen("tcp", "127.0.0.1:0") require.NoError(t, err) - // Init fake grpc Kube service. + // Init fake gRPC Kube service. initGRPCServer(t, env, listener) addr := utils.MustParseAddr(listener.Addr().String()) proxy.handler.handler.cfg.ProxyWebAddr = *addr @@ -7746,11 +7747,11 @@ func createProxy(ctx context.Context, t *testing.T, proxyID string, node *regula sshGRPCServer := grpc.NewServer( grpc.ChainUnaryInterceptor( - utils.GRPCServerUnaryErrorInterceptor, + interceptors.GRPCServerUnaryErrorInterceptor, otelgrpc.UnaryServerInterceptor(), ), grpc.ChainStreamInterceptor( - utils.GRPCServerStreamErrorInterceptor, + interceptors.GRPCServerStreamErrorInterceptor, otelgrpc.StreamServerInterceptor(), ), grpc.Creds(creds), @@ -9006,7 +9007,7 @@ func TestGetIsDashboard(t *testing.T) { } } -// initGRPCServer creates a grpc server serving on the provided listener. +// initGRPCServer creates a gRPC server serving on the provided listener. func initGRPCServer(t *testing.T, env *webPack, listener net.Listener) { clusterName := env.server.ClusterName() // Auth client, lock watcher and authorizer for Kube proxy. diff --git a/web/packages/teleterm/README.md b/web/packages/teleterm/README.md index 0649aa3f4499..59f5cd7ea3e2 100644 --- a/web/packages/teleterm/README.md +++ b/web/packages/teleterm/README.md @@ -186,7 +186,7 @@ resource availability as possible. | | | v | | +--------+---------------+ | | - | | SNI/ALPN | | GRPC + | | SNI/ALPN | | gRPC +--+----------------------+ | routing | | | | | | | | local proxies +-+ | | @@ -205,7 +205,7 @@ resource availability as possible. +-------------+--------------+ +-------------------------------+ +--------+-----------------+ ^ ^ | Terminal | | | - | Electron Main Process | | GRPC API | GRPC API + | Electron Main Process | | gRPC API | gRPC API +-----------+--------------+ | (domain socket) | (domain socket) ^ | | | | |