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