-
Notifications
You must be signed in to change notification settings - Fork 87
/
interfaces.go
242 lines (204 loc) · 9.66 KB
/
interfaces.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package interfaces
import (
"context"
"io"
"net/http"
"time"
"github.com/buildbuddy-io/buildbuddy/server/tables"
aclpb "github.com/buildbuddy-io/buildbuddy/proto/acl"
apipb "github.com/buildbuddy-io/buildbuddy/proto/api/v1"
espb "github.com/buildbuddy-io/buildbuddy/proto/execution_stats"
grpb "github.com/buildbuddy-io/buildbuddy/proto/group"
inpb "github.com/buildbuddy-io/buildbuddy/proto/invocation"
pepb "github.com/buildbuddy-io/buildbuddy/proto/publish_build_event"
repb "github.com/buildbuddy-io/buildbuddy/proto/remote_execution"
scpb "github.com/buildbuddy-io/buildbuddy/proto/scheduler"
telpb "github.com/buildbuddy-io/buildbuddy/proto/telemetry"
)
// An interface representing the user info gleaned from an authorization header.
type UserToken interface {
GetIssuer() string
GetSubscriber() string
// Returns a fq string usable as an ID for this issuer + subscriber.
GetSubID() string
}
// An interface representing the user info gleaned from http basic auth, which is
// often set for GRPC requests.
type BasicAuthToken interface {
GetUser() string
GetPassword() string
}
type UserInfo interface {
GetUserID() string
GetGroupID() string
GetAllowedGroups() []string
IsAdmin() bool
}
type Authenticator interface {
// Redirect to configured authentication provider.
Login(w http.ResponseWriter, r *http.Request)
// Clear any logout state.
Logout(w http.ResponseWriter, r *http.Request)
// Handle a callback from authentication provider.
Auth(w http.ResponseWriter, r *http.Request)
// Called by the authentication handler to authenticate a request. If a
// user was authenticated, a new context will be returned that contains
// a UserToken.
AuthenticateHTTPRequest(w http.ResponseWriter, r *http.Request) context.Context
// Called by the authentication handler to authenticate a request. If a
// user was authenticated, a new context will be returned that contains
// a BasicAuthToken.
AuthenticateGRPCRequest(ctx context.Context) context.Context
// FillUser may be used to construct an initial tables.User object. It
// is filled based on information from the authenticator's JWT.
FillUser(ctx context.Context, user *tables.User) error
// Returns the UserInfo extracted from any authorization headers
// present in the request.
AuthenticatedUser(ctx context.Context) (UserInfo, error)
// Parses and returns a BuildBuddy API key from the given string.
ParseAPIKeyFromString(string) string
// Returns a context containing the given API key.
AuthContextFromAPIKey(ctx context.Context, apiKey string) context.Context
}
type BuildEventChannel interface {
MarkInvocationDisconnected(ctx context.Context, iid string) error
FinalizeInvocation(ctx context.Context, iid string) error
HandleEvent(ctx context.Context, event *pepb.PublishBuildToolEventStreamRequest) error
}
type BuildEventHandler interface {
OpenChannel(ctx context.Context, iid string) BuildEventChannel
}
// A Blobstore must allow for reading, writing, and deleting blobs.
// Implementations should return "os"-compatible package type errors, for
// example, if a file does not exist on Read, the blobstore should return an
// "os.ErrNotExist" error.
type Blobstore interface {
BlobExists(ctx context.Context, blobName string) (bool, error)
ReadBlob(ctx context.Context, blobName string) ([]byte, error)
WriteBlob(ctx context.Context, blobName string, data []byte) (int, error)
DeleteBlob(ctx context.Context, blobName string) error
}
// Similar to a blobstore, a cache allows for reading and writing data, but
// additionally it is responsible for deleting data that is past TTL to keep to
// a manageable size.
// Similar to the Cache above, a digest cache allows for more intelligent
// storing of blob data based on its size.
type Cache interface {
// Returns a new Cache that will store everything under the prefix
// specified by "prefix". The prefix specified is concatenated onto the
// currently set prefix -- so this is a relative operation, not an
// absolute one.
WithPrefix(prefix string) Cache
// Normal cache-like operations.
Contains(ctx context.Context, d *repb.Digest) (bool, error)
ContainsMulti(ctx context.Context, digests []*repb.Digest) (map[*repb.Digest]bool, error)
Get(ctx context.Context, d *repb.Digest) ([]byte, error)
GetMulti(ctx context.Context, digests []*repb.Digest) (map[*repb.Digest][]byte, error)
Set(ctx context.Context, d *repb.Digest, data []byte) error
SetMulti(ctx context.Context, kvs map[*repb.Digest][]byte) error
Delete(ctx context.Context, d *repb.Digest) error
// Low level interface used for seeking and stream-writing.
Reader(ctx context.Context, d *repb.Digest, offset int64) (io.Reader, error)
Writer(ctx context.Context, d *repb.Digest) (io.WriteCloser, error)
// Begin garbage collection and any other necessary background tasks.
Start() error
// Stop garbage collection etc.
Stop() error
}
type InvocationDB interface {
// Invocations API
InsertOrUpdateInvocation(ctx context.Context, in *tables.Invocation) error
UpdateInvocationACL(ctx context.Context, authenticatedUser *UserInfo, invocationID string, acl *aclpb.ACL) error
LookupInvocation(ctx context.Context, invocationID string) (*tables.Invocation, error)
LookupGroupFromInvocation(ctx context.Context, invocationID string) (*tables.Group, error)
LookupExpiredInvocations(ctx context.Context, cutoffTime time.Time, limit int) ([]*tables.Invocation, error)
DeleteInvocation(ctx context.Context, invocationID string) error
DeleteInvocationWithPermsCheck(ctx context.Context, authenticatedUser *UserInfo, invocationID string) error
FillCounts(ctx context.Context, log *telpb.TelemetryStat) error
}
type AuthDB interface {
InsertOrUpdateUserToken(ctx context.Context, subID string, token *tables.Token) error
ReadToken(ctx context.Context, subID string) (*tables.Token, error)
}
type UserDB interface {
// User API
InsertUser(ctx context.Context, u *tables.User) error
// GetUser will return the registered user's information or
// an error if no registered user was found. It requires that a
// valid authenticator is present in the environment and will return
// a UserToken given the provided context.
GetUser(ctx context.Context) (*tables.User, error)
DeleteUser(ctx context.Context, userID string) error
FillCounts(ctx context.Context, stat *telpb.TelemetryStat) error
// Creates the DEFAULT group, for on-prem usage where there is only
// one group and all users are implicitly a part of it.
CreateDefaultGroup(ctx context.Context) error
// Groups API
InsertOrUpdateGroup(ctx context.Context, g *tables.Group) (string, error)
GetGroupByID(ctx context.Context, groupID string) (*tables.Group, error)
GetGroupByURLIdentifier(ctx context.Context, urlIdentifier string) (*tables.Group, error)
GetAuthGroup(ctx context.Context) (*tables.Group, error)
DeleteGroup(ctx context.Context, groupID string) error
AddUserToGroup(ctx context.Context, userID string, groupID string) error
RequestToJoinGroup(ctx context.Context, userID string, groupID string) error
GetGroupUsers(ctx context.Context, groupID string, statuses []grpb.GroupMembershipStatus) ([]*grpb.GetGroupUsersResponse_GroupUser, error)
UpdateGroupUsers(ctx context.Context, groupID string, updates []*grpb.UpdateGroupUsersRequest_Update) error
}
// A webhook can be called when a build is completed.
type Webhook interface {
NotifyComplete(ctx context.Context, invocation *inpb.Invocation) error
}
// Allows aggregating invocation statistics.
type InvocationStatService interface {
GetInvocationStat(ctx context.Context, req *inpb.GetInvocationStatRequest) (*inpb.GetInvocationStatResponse, error)
}
// Allows searching invocations.
type InvocationSearchService interface {
IndexInvocation(ctx context.Context, invocation *inpb.Invocation) error
QueryInvocations(ctx context.Context, req *inpb.SearchInvocationRequest) (*inpb.SearchInvocationResponse, error)
}
type ApiService interface {
apipb.ApiServiceServer
http.Handler
}
type SplashPrinter interface {
PrintSplashScreen(port, grpcPort int)
}
type RemoteExecutionService interface {
Execute(req *repb.ExecuteRequest, stream repb.Execution_ExecuteServer) error
WaitExecution(req *repb.WaitExecutionRequest, stream repb.Execution_WaitExecutionServer) error
PublishOperation(stream repb.Execution_PublishOperationServer) error
}
type FileCache interface {
FastLinkFile(d *repb.Digest, outputPath string) bool
AddFile(d *repb.Digest, existingFilePath string)
}
type SchedulerService interface {
RegisterNode(stream scpb.Scheduler_RegisterNodeServer) error
LeaseTask(stream scpb.Scheduler_LeaseTaskServer) error
ScheduleTask(ctx context.Context, req *scpb.ScheduleTaskRequest) (*scpb.ScheduleTaskResponse, error)
ReEnqueueTask(ctx context.Context, req *scpb.ReEnqueueTaskRequest) (*scpb.ReEnqueueTaskResponse, error)
}
type ExecutionService interface {
GetExecution(ctx context.Context, req *espb.GetExecutionRequest) (*espb.GetExecutionResponse, error)
}
type Subscriber interface {
Close() error
Chan() <-chan string
}
// A PubSub allows for sending messages between distributed (cross process,
// cross machine) processes. This may be implemented by a cloud-pubsub service,
// or something like redis.
type PubSub interface {
Publish(ctx context.Context, channelName string, message string) error
Subscribe(ctx context.Context, channelName string) Subscriber
}
// A MetricsCollector allows for storing ephemeral values globally.
//
// No guarantees are made about durability of MetricsCollectors -- they may be
// evicted from the backing store that maintains them (usually memcache or
// redis), so they should *not* be used in critical path code.
type MetricsCollector interface {
IncrementCount(ctx context.Context, counterName string, n int64) (int64, error)
ReadCount(ctx context.Context, counterName string) (int64, error)
}