@@ -6,60 +6,48 @@ package apiv1
6
6
7
7
import (
8
8
"context"
9
+ "fmt"
9
10
11
+ connect "github.com/bufbuild/connect-go"
10
12
protocol "github.com/gitpod-io/gitpod/gitpod-protocol"
13
+ "github.com/gitpod-io/gitpod/public-api-server/pkg/auth"
11
14
"github.com/gitpod-io/gitpod/public-api-server/pkg/proxy"
12
15
v1 "github.com/gitpod-io/gitpod/public-api/v1"
16
+ "github.com/gitpod-io/gitpod/public-api/v1/v1connect"
13
17
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
14
18
"github.com/relvacode/iso8601"
15
- "google.golang.org/grpc"
16
- "google.golang.org/grpc/codes"
17
- "google.golang.org/grpc/metadata"
18
- "google.golang.org/grpc/status"
19
19
"google.golang.org/protobuf/types/known/timestamppb"
20
20
)
21
21
22
22
func NewWorkspaceService (serverConnPool proxy.ServerConnectionPool ) * WorkspaceService {
23
23
return & WorkspaceService {
24
- connectionPool : serverConnPool ,
25
- UnimplementedWorkspacesServiceServer : & v1.UnimplementedWorkspacesServiceServer {},
24
+ connectionPool : serverConnPool ,
26
25
}
27
26
}
28
27
29
28
type WorkspaceService struct {
30
29
connectionPool proxy.ServerConnectionPool
31
30
32
- * v1. UnimplementedWorkspacesServiceServer
31
+ v1connect. UnimplementedWorkspacesServiceHandler
33
32
}
34
33
35
- func (w * WorkspaceService ) GetWorkspace (ctx context.Context , r * v1.GetWorkspaceRequest ) (* v1.GetWorkspaceResponse , error ) {
34
+ func (s * WorkspaceService ) GetWorkspace (ctx context.Context , req * connect.Request [v1.GetWorkspaceRequest ]) (* connect.Response [v1.GetWorkspaceResponse ], error ) {
35
+ token := auth .TokenFromContext (ctx )
36
36
logger := ctxlogrus .Extract (ctx )
37
- token , err := bearerTokenFromContext (ctx )
38
- if err != nil {
39
- return nil , err
40
- }
41
37
42
- server , err := w .connectionPool .Get (ctx , token )
38
+ server , err := s .connectionPool .Get (ctx , token )
43
39
if err != nil {
44
40
logger .WithError (err ).Error ("Failed to get connection to server." )
45
- return nil , status . Error ( codes . Internal , "failed to establish connection to downstream services" )
41
+ return nil , connect . NewError ( connect . CodeInternal , err )
46
42
}
47
43
48
- workspace , err := server .GetWorkspace (ctx , r .GetWorkspaceId ())
44
+ workspace , err := server .GetWorkspace (ctx , req . Msg .GetWorkspaceId ())
49
45
if err != nil {
50
46
logger .WithError (err ).Error ("Failed to get workspace." )
51
- converted := proxy .ConvertError (err )
52
- switch status .Code (converted ) {
53
- case codes .PermissionDenied :
54
- return nil , status .Error (codes .PermissionDenied , "insufficient permission to access workspace" )
55
- case codes .NotFound :
56
- return nil , status .Error (codes .NotFound , "workspace does not exist" )
57
- default :
58
- return nil , status .Error (codes .Internal , "unable to retrieve workspace" )
59
- }
47
+ return nil , proxy .ConvertError (err )
60
48
}
61
49
62
- return & v1.GetWorkspaceResponse {
50
+ return connect . NewResponse ( & v1.GetWorkspaceResponse {
63
51
Result : & v1.Workspace {
64
52
WorkspaceId : workspace .Workspace .ID ,
65
53
OwnerId : workspace .Workspace .OwnerID ,
@@ -73,72 +61,40 @@ func (w *WorkspaceService) GetWorkspace(ctx context.Context, r *v1.GetWorkspaceR
73
61
},
74
62
Description : workspace .Workspace .Description ,
75
63
},
76
- }, nil
64
+ }) , nil
77
65
}
78
66
79
- func (w * WorkspaceService ) GetOwnerToken (ctx context.Context , r * v1.GetOwnerTokenRequest ) (* v1.GetOwnerTokenResponse , error ) {
67
+ func (s * WorkspaceService ) GetOwnerToken (ctx context.Context , req * connect. Request [ v1.GetOwnerTokenRequest ] ) (* connect. Response [ v1.GetOwnerTokenResponse ] , error ) {
80
68
logger := ctxlogrus .Extract (ctx )
81
- token , err := bearerTokenFromContext (ctx )
82
- if err != nil {
83
- return nil , err
84
- }
69
+ token := auth .TokenFromContext (ctx )
85
70
86
- server , err := w .connectionPool .Get (ctx , token )
71
+ server , err := s .connectionPool .Get (ctx , token )
87
72
if err != nil {
88
73
logger .WithError (err ).Error ("Failed to get connection to server." )
89
- return nil , status . Error ( codes . Internal , "failed to establish connection to downstream services" )
74
+ return nil , connect . NewError ( connect . CodeInternal , fmt . Errorf ( "failed to establish connection to downstream services" ) )
90
75
}
91
76
92
- ownerToken , err := server .GetOwnerToken (ctx , r .GetWorkspaceId ())
77
+ ownerToken , err := server .GetOwnerToken (ctx , req . Msg .GetWorkspaceId ())
93
78
94
79
if err != nil {
95
80
logger .WithError (err ).Error ("Failed to get owner token." )
96
- converted := proxy .ConvertError (err )
97
- switch status .Code (converted ) {
98
- case codes .PermissionDenied :
99
- return nil , status .Error (codes .PermissionDenied , "insufficient permission to retrieve ownertoken" )
100
- case codes .NotFound :
101
- return nil , status .Error (codes .NotFound , "workspace does not exist" )
102
- default :
103
- return nil , status .Error (codes .Internal , "unable to retrieve owner token" )
104
- }
105
- }
106
-
107
- return & v1.GetOwnerTokenResponse {Token : ownerToken }, nil
108
- }
109
-
110
- func bearerTokenFromContext (ctx context.Context ) (string , error ) {
111
- md , ok := metadata .FromIncomingContext (ctx )
112
- if ! ok {
113
- return "" , status .Error (codes .Unauthenticated , "no credentials provided" )
114
- }
115
-
116
- values := md .Get ("authorization" )
117
- if len (values ) == 0 {
118
- return "" , status .Error (codes .Unauthenticated , "no authorization header specified" )
119
- }
120
- if len (values ) > 1 {
121
- return "" , status .Error (codes .Unauthenticated , "more than one authorization header specified, exactly one is required" )
81
+ return nil , proxy .ConvertError (err )
122
82
}
123
83
124
- token := values [0 ]
125
- return token , nil
84
+ return connect .NewResponse (& v1.GetOwnerTokenResponse {Token : ownerToken }), nil
126
85
}
127
86
128
- func (w * WorkspaceService ) ListWorkspaces (ctx context.Context , req * v1.ListWorkspacesRequest ) (* v1.ListWorkspacesResponse , error ) {
87
+ func (s * WorkspaceService ) ListWorkspaces (ctx context.Context , req * connect. Request [ v1.ListWorkspacesRequest ] ) (* connect. Response [ v1.ListWorkspacesResponse ] , error ) {
129
88
logger := ctxlogrus .Extract (ctx )
130
- token , err := bearerTokenFromContext (ctx )
131
- if err != nil {
132
- return nil , err
133
- }
89
+ token := auth .TokenFromContext (ctx )
134
90
135
- server , err := w .connectionPool .Get (ctx , token )
91
+ server , err := s .connectionPool .Get (ctx , token )
136
92
if err != nil {
137
93
logger .WithError (err ).Error ("Failed to get connection to server." )
138
- return nil , status . Error ( codes . Internal , "failed to establish connection to downstream services" )
94
+ return nil , connect . NewError ( connect . CodeInternal , fmt . Errorf ( "failed to establish connection to downstream services" ) )
139
95
}
140
96
141
- limit , err := getLimitFromPagination (req .Pagination )
97
+ limit , err := getLimitFromPagination (req .Msg . GetPagination () )
142
98
if err != nil {
143
99
// getLimitFromPagination returns gRPC errors
144
100
return nil , err
@@ -161,9 +117,11 @@ func (w *WorkspaceService) ListWorkspaces(ctx context.Context, req *v1.ListWorks
161
117
res = append (res , workspaceAndInstance )
162
118
}
163
119
164
- return & v1.ListWorkspacesResponse {
165
- Result : res ,
166
- }, nil
120
+ return connect .NewResponse (
121
+ & v1.ListWorkspacesResponse {
122
+ Result : res ,
123
+ },
124
+ ), nil
167
125
}
168
126
169
127
func getLimitFromPagination (pagination * v1.Pagination ) (int , error ) {
@@ -179,7 +137,7 @@ func getLimitFromPagination(pagination *v1.Pagination) (int, error) {
179
137
return defaultLimit , nil
180
138
}
181
139
if pagination .PageSize < 0 || maxLimit < pagination .PageSize {
182
- return 0 , grpc . Errorf ( codes . InvalidArgument , "invalid pagination page size (must be 0 < x < %d)" , maxLimit )
140
+ return 0 , connect . NewError ( connect . CodeInvalidArgument , fmt . Errorf ( "invalid pagination page size (must be 0 < x < %d)" , maxLimit ) )
183
141
}
184
142
185
143
return int (pagination .PageSize ), nil
@@ -192,7 +150,7 @@ func convertWorkspaceInfo(input *protocol.WorkspaceInfo) (*v1.ListWorkspacesResp
192
150
creationTime , err := parseGitpodTimestamp (wsi .CreationTime )
193
151
if err != nil {
194
152
// TODO(cw): should this really return an error and possibly fail the entire operation?
195
- return nil , grpc . Errorf ( codes . FailedPrecondition , "cannot parse creation time: %v" , err )
153
+ return nil , connect . NewError ( connect . CodeFailedPrecondition , fmt . Errorf ( "cannot parse creation time: %v" , err ) )
196
154
}
197
155
198
156
var phase v1.WorkspaceInstanceStatus_Phase
@@ -219,7 +177,7 @@ func convertWorkspaceInfo(input *protocol.WorkspaceInfo) (*v1.ListWorkspacesResp
219
177
phase = v1 .WorkspaceInstanceStatus_PHASE_STOPPED
220
178
default :
221
179
// TODO(cw): should this really return an error and possibly fail the entire operation?
222
- return nil , grpc . Errorf ( codes . FailedPrecondition , "cannot convert instance phase: %s" , wsi .Status .Phase )
180
+ return nil , connect . NewError ( connect . CodeFailedPrecondition , fmt . Errorf ( "cannot convert instance phase: %s" , wsi .Status .Phase ) )
223
181
}
224
182
225
183
var admissionLevel v1.AdmissionLevel
0 commit comments