20318: Route KeepClient block writes through disk cache.
[arvados.git] / sdk / go / arvados / api.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package arvados
6
7 import (
8         "bufio"
9         "context"
10         "encoding/json"
11         "io"
12         "net"
13         "net/http"
14
15         "github.com/sirupsen/logrus"
16 )
17
18 type APIEndpoint struct {
19         Method string
20         Path   string
21         // "new attributes" key for create/update requests
22         AttrsKey string
23 }
24
25 var (
26         EndpointConfigGet                     = APIEndpoint{"GET", "arvados/v1/config", ""}
27         EndpointVocabularyGet                 = APIEndpoint{"GET", "arvados/v1/vocabulary", ""}
28         EndpointLogin                         = APIEndpoint{"GET", "login", ""}
29         EndpointLogout                        = APIEndpoint{"GET", "logout", ""}
30         EndpointAuthorizedKeyCreate           = APIEndpoint{"POST", "arvados/v1/authorized_keys", "authorized_key"}
31         EndpointAuthorizedKeyUpdate           = APIEndpoint{"PATCH", "arvados/v1/authorized_keys/{uuid}", "authorized_key"}
32         EndpointAuthorizedKeyGet              = APIEndpoint{"GET", "arvados/v1/authorized_keys/{uuid}", ""}
33         EndpointAuthorizedKeyList             = APIEndpoint{"GET", "arvados/v1/authorized_keys", ""}
34         EndpointAuthorizedKeyDelete           = APIEndpoint{"DELETE", "arvados/v1/authorized_keys/{uuid}", ""}
35         EndpointCollectionCreate              = APIEndpoint{"POST", "arvados/v1/collections", "collection"}
36         EndpointCollectionUpdate              = APIEndpoint{"PATCH", "arvados/v1/collections/{uuid}", "collection"}
37         EndpointCollectionGet                 = APIEndpoint{"GET", "arvados/v1/collections/{uuid}", ""}
38         EndpointCollectionList                = APIEndpoint{"GET", "arvados/v1/collections", ""}
39         EndpointCollectionProvenance          = APIEndpoint{"GET", "arvados/v1/collections/{uuid}/provenance", ""}
40         EndpointCollectionUsedBy              = APIEndpoint{"GET", "arvados/v1/collections/{uuid}/used_by", ""}
41         EndpointCollectionDelete              = APIEndpoint{"DELETE", "arvados/v1/collections/{uuid}", ""}
42         EndpointCollectionTrash               = APIEndpoint{"POST", "arvados/v1/collections/{uuid}/trash", ""}
43         EndpointCollectionUntrash             = APIEndpoint{"POST", "arvados/v1/collections/{uuid}/untrash", ""}
44         EndpointSpecimenCreate                = APIEndpoint{"POST", "arvados/v1/specimens", "specimen"}
45         EndpointSpecimenUpdate                = APIEndpoint{"PATCH", "arvados/v1/specimens/{uuid}", "specimen"}
46         EndpointSpecimenGet                   = APIEndpoint{"GET", "arvados/v1/specimens/{uuid}", ""}
47         EndpointSpecimenList                  = APIEndpoint{"GET", "arvados/v1/specimens", ""}
48         EndpointSpecimenDelete                = APIEndpoint{"DELETE", "arvados/v1/specimens/{uuid}", ""}
49         EndpointContainerCreate               = APIEndpoint{"POST", "arvados/v1/containers", "container"}
50         EndpointContainerUpdate               = APIEndpoint{"PATCH", "arvados/v1/containers/{uuid}", "container"}
51         EndpointContainerPriorityUpdate       = APIEndpoint{"POST", "arvados/v1/containers/{uuid}/update_priority", "container"}
52         EndpointContainerGet                  = APIEndpoint{"GET", "arvados/v1/containers/{uuid}", ""}
53         EndpointContainerList                 = APIEndpoint{"GET", "arvados/v1/containers", ""}
54         EndpointContainerDelete               = APIEndpoint{"DELETE", "arvados/v1/containers/{uuid}", ""}
55         EndpointContainerLock                 = APIEndpoint{"POST", "arvados/v1/containers/{uuid}/lock", ""}
56         EndpointContainerUnlock               = APIEndpoint{"POST", "arvados/v1/containers/{uuid}/unlock", ""}
57         EndpointContainerSSH                  = APIEndpoint{"POST", "arvados/v1/containers/{uuid}/ssh", ""}
58         EndpointContainerSSHCompat            = APIEndpoint{"POST", "arvados/v1/connect/{uuid}/ssh", ""} // for compatibility with arvados <2.7
59         EndpointContainerGatewayTunnel        = APIEndpoint{"POST", "arvados/v1/containers/{uuid}/gateway_tunnel", ""}
60         EndpointContainerGatewayTunnelCompat  = APIEndpoint{"POST", "arvados/v1/connect/{uuid}/gateway_tunnel", ""} // for compatibility with arvados <2.7
61         EndpointContainerRequestCreate        = APIEndpoint{"POST", "arvados/v1/container_requests", "container_request"}
62         EndpointContainerRequestUpdate        = APIEndpoint{"PATCH", "arvados/v1/container_requests/{uuid}", "container_request"}
63         EndpointContainerRequestGet           = APIEndpoint{"GET", "arvados/v1/container_requests/{uuid}", ""}
64         EndpointContainerRequestList          = APIEndpoint{"GET", "arvados/v1/container_requests", ""}
65         EndpointContainerRequestDelete        = APIEndpoint{"DELETE", "arvados/v1/container_requests/{uuid}", ""}
66         EndpointContainerRequestLog           = APIEndpoint{"GET", "arvados/v1/container_requests/{uuid}/log{path:|/.*}", ""}
67         EndpointGroupCreate                   = APIEndpoint{"POST", "arvados/v1/groups", "group"}
68         EndpointGroupUpdate                   = APIEndpoint{"PATCH", "arvados/v1/groups/{uuid}", "group"}
69         EndpointGroupGet                      = APIEndpoint{"GET", "arvados/v1/groups/{uuid}", ""}
70         EndpointGroupList                     = APIEndpoint{"GET", "arvados/v1/groups", ""}
71         EndpointGroupContents                 = APIEndpoint{"GET", "arvados/v1/groups/contents", ""}
72         EndpointGroupContentsUUIDInPath       = APIEndpoint{"GET", "arvados/v1/groups/{uuid}/contents", ""} // Alternative HTTP route; client-side code should always use EndpointGroupContents instead
73         EndpointGroupShared                   = APIEndpoint{"GET", "arvados/v1/groups/shared", ""}
74         EndpointGroupDelete                   = APIEndpoint{"DELETE", "arvados/v1/groups/{uuid}", ""}
75         EndpointGroupTrash                    = APIEndpoint{"POST", "arvados/v1/groups/{uuid}/trash", ""}
76         EndpointGroupUntrash                  = APIEndpoint{"POST", "arvados/v1/groups/{uuid}/untrash", ""}
77         EndpointLinkCreate                    = APIEndpoint{"POST", "arvados/v1/links", "link"}
78         EndpointLinkUpdate                    = APIEndpoint{"PATCH", "arvados/v1/links/{uuid}", "link"}
79         EndpointLinkGet                       = APIEndpoint{"GET", "arvados/v1/links/{uuid}", ""}
80         EndpointLinkList                      = APIEndpoint{"GET", "arvados/v1/links", ""}
81         EndpointLinkDelete                    = APIEndpoint{"DELETE", "arvados/v1/links/{uuid}", ""}
82         EndpointLogCreate                     = APIEndpoint{"POST", "arvados/v1/logs", "log"}
83         EndpointLogUpdate                     = APIEndpoint{"PATCH", "arvados/v1/logs/{uuid}", "log"}
84         EndpointLogGet                        = APIEndpoint{"GET", "arvados/v1/logs/{uuid}", ""}
85         EndpointLogList                       = APIEndpoint{"GET", "arvados/v1/logs", ""}
86         EndpointLogDelete                     = APIEndpoint{"DELETE", "arvados/v1/logs/{uuid}", ""}
87         EndpointSysTrashSweep                 = APIEndpoint{"POST", "sys/trash_sweep", ""}
88         EndpointUserActivate                  = APIEndpoint{"POST", "arvados/v1/users/{uuid}/activate", ""}
89         EndpointUserCreate                    = APIEndpoint{"POST", "arvados/v1/users", "user"}
90         EndpointUserCurrent                   = APIEndpoint{"GET", "arvados/v1/users/current", ""}
91         EndpointUserDelete                    = APIEndpoint{"DELETE", "arvados/v1/users/{uuid}", ""}
92         EndpointUserGet                       = APIEndpoint{"GET", "arvados/v1/users/{uuid}", ""}
93         EndpointUserGetCurrent                = APIEndpoint{"GET", "arvados/v1/users/current", ""}
94         EndpointUserGetSystem                 = APIEndpoint{"GET", "arvados/v1/users/system", ""}
95         EndpointUserList                      = APIEndpoint{"GET", "arvados/v1/users", ""}
96         EndpointUserMerge                     = APIEndpoint{"POST", "arvados/v1/users/merge", ""}
97         EndpointUserSetup                     = APIEndpoint{"POST", "arvados/v1/users/setup", "user"}
98         EndpointUserSystem                    = APIEndpoint{"GET", "arvados/v1/users/system", ""}
99         EndpointUserUnsetup                   = APIEndpoint{"POST", "arvados/v1/users/{uuid}/unsetup", ""}
100         EndpointUserUpdate                    = APIEndpoint{"PATCH", "arvados/v1/users/{uuid}", "user"}
101         EndpointUserBatchUpdate               = APIEndpoint{"PATCH", "arvados/v1/users/batch_update", ""}
102         EndpointUserAuthenticate              = APIEndpoint{"POST", "arvados/v1/users/authenticate", ""}
103         EndpointAPIClientAuthorizationCurrent = APIEndpoint{"GET", "arvados/v1/api_client_authorizations/current", ""}
104         EndpointAPIClientAuthorizationCreate  = APIEndpoint{"POST", "arvados/v1/api_client_authorizations", "api_client_authorization"}
105         EndpointAPIClientAuthorizationUpdate  = APIEndpoint{"PUT", "arvados/v1/api_client_authorizations/{uuid}", "api_client_authorization"}
106         EndpointAPIClientAuthorizationList    = APIEndpoint{"GET", "arvados/v1/api_client_authorizations", ""}
107         EndpointAPIClientAuthorizationDelete  = APIEndpoint{"DELETE", "arvados/v1/api_client_authorizations/{uuid}", ""}
108         EndpointAPIClientAuthorizationGet     = APIEndpoint{"GET", "arvados/v1/api_client_authorizations/{uuid}", ""}
109 )
110
111 type ContainerSSHOptions struct {
112         UUID          string `json:"uuid"`
113         DetachKeys    string `json:"detach_keys"`
114         LoginUsername string `json:"login_username"`
115         NoForward     bool   `json:"no_forward"`
116 }
117
118 type ConnectionResponse struct {
119         Conn   net.Conn           `json:"-"`
120         Bufrw  *bufio.ReadWriter  `json:"-"`
121         Logger logrus.FieldLogger `json:"-"`
122         Header http.Header        `json:"-"`
123 }
124
125 type ContainerGatewayTunnelOptions struct {
126         UUID       string `json:"uuid"`
127         AuthSecret string `json:"auth_secret"`
128 }
129
130 type GetOptions struct {
131         UUID         string   `json:"uuid,omitempty"`
132         Select       []string `json:"select"`
133         IncludeTrash bool     `json:"include_trash"`
134         ForwardedFor string   `json:"forwarded_for,omitempty"`
135         Remote       string   `json:"remote,omitempty"`
136 }
137
138 type UntrashOptions struct {
139         UUID             string `json:"uuid"`
140         EnsureUniqueName bool   `json:"ensure_unique_name"`
141 }
142
143 type ListOptions struct {
144         ClusterID          string                 `json:"cluster_id"`
145         Select             []string               `json:"select"`
146         Filters            []Filter               `json:"filters"`
147         Where              map[string]interface{} `json:"where"`
148         Limit              int64                  `json:"limit"`
149         Offset             int64                  `json:"offset"`
150         Order              []string               `json:"order"`
151         Distinct           bool                   `json:"distinct"`
152         Count              string                 `json:"count"`
153         IncludeTrash       bool                   `json:"include_trash"`
154         IncludeOldVersions bool                   `json:"include_old_versions"`
155         BypassFederation   bool                   `json:"bypass_federation"`
156         ForwardedFor       string                 `json:"forwarded_for,omitempty"`
157         Include            string                 `json:"include"`
158 }
159
160 type CreateOptions struct {
161         ClusterID        string                 `json:"cluster_id"`
162         EnsureUniqueName bool                   `json:"ensure_unique_name"`
163         Select           []string               `json:"select"`
164         Attrs            map[string]interface{} `json:"attrs"`
165         // ReplaceFiles only applies when creating a collection.
166         ReplaceFiles map[string]string `json:"replace_files"`
167 }
168
169 type UpdateOptions struct {
170         UUID             string                 `json:"uuid"`
171         Attrs            map[string]interface{} `json:"attrs"`
172         Select           []string               `json:"select"`
173         BypassFederation bool                   `json:"bypass_federation"`
174         // ReplaceFiles only applies when updating a collection.
175         ReplaceFiles map[string]string `json:"replace_files"`
176 }
177
178 type GroupContentsOptions struct {
179         ClusterID          string   `json:"cluster_id"`
180         UUID               string   `json:"uuid,omitempty"`
181         Select             []string `json:"select"`
182         Filters            []Filter `json:"filters"`
183         Limit              int64    `json:"limit"`
184         Offset             int64    `json:"offset"`
185         Order              []string `json:"order"`
186         Distinct           bool     `json:"distinct"`
187         Count              string   `json:"count"`
188         Include            string   `json:"include"`
189         Recursive          bool     `json:"recursive"`
190         IncludeTrash       bool     `json:"include_trash"`
191         IncludeOldVersions bool     `json:"include_old_versions"`
192         ExcludeHomeProject bool     `json:"exclude_home_project"`
193 }
194
195 type UserActivateOptions struct {
196         UUID string `json:"uuid"`
197 }
198
199 type UserSetupOptions struct {
200         UUID                  string                 `json:"uuid,omitempty"`
201         Email                 string                 `json:"email,omitempty"`
202         OpenIDPrefix          string                 `json:"openid_prefix,omitempty"`
203         RepoName              string                 `json:"repo_name,omitempty"`
204         VMUUID                string                 `json:"vm_uuid,omitempty"`
205         SendNotificationEmail bool                   `json:"send_notification_email,omitempty"`
206         Attrs                 map[string]interface{} `json:"attrs"`
207 }
208
209 type UserMergeOptions struct {
210         NewUserUUID       string `json:"new_user_uuid,omitempty"`
211         OldUserUUID       string `json:"old_user_uuid,omitempty"`
212         NewOwnerUUID      string `json:"new_owner_uuid,omitempty"`
213         NewUserToken      string `json:"new_user_token,omitempty"`
214         RedirectToNewUser bool   `json:"redirect_to_new_user"`
215 }
216
217 type UserBatchUpdateOptions struct {
218         Updates map[string]map[string]interface{} `json:"updates"`
219 }
220
221 type UserBatchUpdateResponse struct{}
222
223 type DeleteOptions struct {
224         UUID string `json:"uuid"`
225 }
226
227 type LoginOptions struct {
228         ReturnTo string `json:"return_to"`        // On success, redirect to this target with api_token=xxx query param
229         Remote   string `json:"remote,omitempty"` // Salt token for remote Cluster ID
230         Code     string `json:"code,omitempty"`   // OAuth2 callback code
231         State    string `json:"state,omitempty"`  // OAuth2 callback state
232 }
233
234 type UserAuthenticateOptions struct {
235         Username string `json:"username,omitempty"` // PAM username
236         Password string `json:"password,omitempty"` // PAM password
237 }
238
239 type LogoutOptions struct {
240         ReturnTo string `json:"return_to"` // Redirect to this URL after logging out
241 }
242
243 type BlockReadOptions struct {
244         Locator string
245         WriteTo io.Writer
246 }
247
248 type BlockWriteOptions struct {
249         Hash           string
250         Data           []byte
251         Reader         io.Reader // Must be set if Data is nil.
252         DataSize       int       // Must be set if Data is nil.
253         RequestID      string
254         StorageClasses []string
255         Replicas       int
256         Attempts       int
257 }
258
259 type BlockWriteResponse struct {
260         Locator  string
261         Replicas int
262 }
263
264 type WebDAVOptions struct {
265         Method string
266         Path   string
267         Header http.Header
268 }
269
270 type ContainerLogOptions struct {
271         UUID      string `json:"uuid"`
272         NoForward bool   `json:"no_forward"`
273         WebDAVOptions
274 }
275
276 type API interface {
277         ConfigGet(ctx context.Context) (json.RawMessage, error)
278         VocabularyGet(ctx context.Context) (Vocabulary, error)
279         Login(ctx context.Context, options LoginOptions) (LoginResponse, error)
280         Logout(ctx context.Context, options LogoutOptions) (LogoutResponse, error)
281         AuthorizedKeyCreate(ctx context.Context, options CreateOptions) (AuthorizedKey, error)
282         AuthorizedKeyUpdate(ctx context.Context, options UpdateOptions) (AuthorizedKey, error)
283         AuthorizedKeyGet(ctx context.Context, options GetOptions) (AuthorizedKey, error)
284         AuthorizedKeyList(ctx context.Context, options ListOptions) (AuthorizedKeyList, error)
285         AuthorizedKeyDelete(ctx context.Context, options DeleteOptions) (AuthorizedKey, error)
286         CollectionCreate(ctx context.Context, options CreateOptions) (Collection, error)
287         CollectionUpdate(ctx context.Context, options UpdateOptions) (Collection, error)
288         CollectionGet(ctx context.Context, options GetOptions) (Collection, error)
289         CollectionList(ctx context.Context, options ListOptions) (CollectionList, error)
290         CollectionProvenance(ctx context.Context, options GetOptions) (map[string]interface{}, error)
291         CollectionUsedBy(ctx context.Context, options GetOptions) (map[string]interface{}, error)
292         CollectionDelete(ctx context.Context, options DeleteOptions) (Collection, error)
293         CollectionTrash(ctx context.Context, options DeleteOptions) (Collection, error)
294         CollectionUntrash(ctx context.Context, options UntrashOptions) (Collection, error)
295         ContainerCreate(ctx context.Context, options CreateOptions) (Container, error)
296         ContainerUpdate(ctx context.Context, options UpdateOptions) (Container, error)
297         ContainerPriorityUpdate(ctx context.Context, options UpdateOptions) (Container, error)
298         ContainerGet(ctx context.Context, options GetOptions) (Container, error)
299         ContainerList(ctx context.Context, options ListOptions) (ContainerList, error)
300         ContainerDelete(ctx context.Context, options DeleteOptions) (Container, error)
301         ContainerLock(ctx context.Context, options GetOptions) (Container, error)
302         ContainerUnlock(ctx context.Context, options GetOptions) (Container, error)
303         ContainerSSH(ctx context.Context, options ContainerSSHOptions) (ConnectionResponse, error)
304         ContainerGatewayTunnel(ctx context.Context, options ContainerGatewayTunnelOptions) (ConnectionResponse, error)
305         ContainerRequestCreate(ctx context.Context, options CreateOptions) (ContainerRequest, error)
306         ContainerRequestUpdate(ctx context.Context, options UpdateOptions) (ContainerRequest, error)
307         ContainerRequestGet(ctx context.Context, options GetOptions) (ContainerRequest, error)
308         ContainerRequestList(ctx context.Context, options ListOptions) (ContainerRequestList, error)
309         ContainerRequestDelete(ctx context.Context, options DeleteOptions) (ContainerRequest, error)
310         ContainerRequestLog(ctx context.Context, options ContainerLogOptions) (http.Handler, error)
311         GroupCreate(ctx context.Context, options CreateOptions) (Group, error)
312         GroupUpdate(ctx context.Context, options UpdateOptions) (Group, error)
313         GroupGet(ctx context.Context, options GetOptions) (Group, error)
314         GroupList(ctx context.Context, options ListOptions) (GroupList, error)
315         GroupContents(ctx context.Context, options GroupContentsOptions) (ObjectList, error)
316         GroupShared(ctx context.Context, options ListOptions) (GroupList, error)
317         GroupDelete(ctx context.Context, options DeleteOptions) (Group, error)
318         GroupTrash(ctx context.Context, options DeleteOptions) (Group, error)
319         GroupUntrash(ctx context.Context, options UntrashOptions) (Group, error)
320         LinkCreate(ctx context.Context, options CreateOptions) (Link, error)
321         LinkUpdate(ctx context.Context, options UpdateOptions) (Link, error)
322         LinkGet(ctx context.Context, options GetOptions) (Link, error)
323         LinkList(ctx context.Context, options ListOptions) (LinkList, error)
324         LinkDelete(ctx context.Context, options DeleteOptions) (Link, error)
325         LogCreate(ctx context.Context, options CreateOptions) (Log, error)
326         LogUpdate(ctx context.Context, options UpdateOptions) (Log, error)
327         LogGet(ctx context.Context, options GetOptions) (Log, error)
328         LogList(ctx context.Context, options ListOptions) (LogList, error)
329         LogDelete(ctx context.Context, options DeleteOptions) (Log, error)
330         SpecimenCreate(ctx context.Context, options CreateOptions) (Specimen, error)
331         SpecimenUpdate(ctx context.Context, options UpdateOptions) (Specimen, error)
332         SpecimenGet(ctx context.Context, options GetOptions) (Specimen, error)
333         SpecimenList(ctx context.Context, options ListOptions) (SpecimenList, error)
334         SpecimenDelete(ctx context.Context, options DeleteOptions) (Specimen, error)
335         SysTrashSweep(ctx context.Context, options struct{}) (struct{}, error)
336         UserCreate(ctx context.Context, options CreateOptions) (User, error)
337         UserUpdate(ctx context.Context, options UpdateOptions) (User, error)
338         UserMerge(ctx context.Context, options UserMergeOptions) (User, error)
339         UserActivate(ctx context.Context, options UserActivateOptions) (User, error)
340         UserSetup(ctx context.Context, options UserSetupOptions) (map[string]interface{}, error)
341         UserUnsetup(ctx context.Context, options GetOptions) (User, error)
342         UserGet(ctx context.Context, options GetOptions) (User, error)
343         UserGetCurrent(ctx context.Context, options GetOptions) (User, error)
344         UserGetSystem(ctx context.Context, options GetOptions) (User, error)
345         UserList(ctx context.Context, options ListOptions) (UserList, error)
346         UserDelete(ctx context.Context, options DeleteOptions) (User, error)
347         UserBatchUpdate(context.Context, UserBatchUpdateOptions) (UserList, error)
348         UserAuthenticate(ctx context.Context, options UserAuthenticateOptions) (APIClientAuthorization, error)
349         APIClientAuthorizationCurrent(ctx context.Context, options GetOptions) (APIClientAuthorization, error)
350         APIClientAuthorizationCreate(ctx context.Context, options CreateOptions) (APIClientAuthorization, error)
351         APIClientAuthorizationList(ctx context.Context, options ListOptions) (APIClientAuthorizationList, error)
352         APIClientAuthorizationDelete(ctx context.Context, options DeleteOptions) (APIClientAuthorization, error)
353         APIClientAuthorizationUpdate(ctx context.Context, options UpdateOptions) (APIClientAuthorization, error)
354         APIClientAuthorizationGet(ctx context.Context, options GetOptions) (APIClientAuthorization, error)
355 }