Merge branch '21258-flaky-adc-test'
[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 BlockWriteOptions struct {
245         Hash           string
246         Data           []byte
247         Reader         io.Reader
248         DataSize       int // Must be set if Data is nil.
249         RequestID      string
250         StorageClasses []string
251         Replicas       int
252         Attempts       int
253 }
254
255 type BlockWriteResponse struct {
256         Locator  string
257         Replicas int
258 }
259
260 type WebDAVOptions struct {
261         Method string
262         Path   string
263         Header http.Header
264 }
265
266 type ContainerLogOptions struct {
267         UUID      string `json:"uuid"`
268         NoForward bool   `json:"no_forward"`
269         WebDAVOptions
270 }
271
272 type API interface {
273         ConfigGet(ctx context.Context) (json.RawMessage, error)
274         VocabularyGet(ctx context.Context) (Vocabulary, error)
275         Login(ctx context.Context, options LoginOptions) (LoginResponse, error)
276         Logout(ctx context.Context, options LogoutOptions) (LogoutResponse, error)
277         AuthorizedKeyCreate(ctx context.Context, options CreateOptions) (AuthorizedKey, error)
278         AuthorizedKeyUpdate(ctx context.Context, options UpdateOptions) (AuthorizedKey, error)
279         AuthorizedKeyGet(ctx context.Context, options GetOptions) (AuthorizedKey, error)
280         AuthorizedKeyList(ctx context.Context, options ListOptions) (AuthorizedKeyList, error)
281         AuthorizedKeyDelete(ctx context.Context, options DeleteOptions) (AuthorizedKey, error)
282         CollectionCreate(ctx context.Context, options CreateOptions) (Collection, error)
283         CollectionUpdate(ctx context.Context, options UpdateOptions) (Collection, error)
284         CollectionGet(ctx context.Context, options GetOptions) (Collection, error)
285         CollectionList(ctx context.Context, options ListOptions) (CollectionList, error)
286         CollectionProvenance(ctx context.Context, options GetOptions) (map[string]interface{}, error)
287         CollectionUsedBy(ctx context.Context, options GetOptions) (map[string]interface{}, error)
288         CollectionDelete(ctx context.Context, options DeleteOptions) (Collection, error)
289         CollectionTrash(ctx context.Context, options DeleteOptions) (Collection, error)
290         CollectionUntrash(ctx context.Context, options UntrashOptions) (Collection, error)
291         ContainerCreate(ctx context.Context, options CreateOptions) (Container, error)
292         ContainerUpdate(ctx context.Context, options UpdateOptions) (Container, error)
293         ContainerPriorityUpdate(ctx context.Context, options UpdateOptions) (Container, error)
294         ContainerGet(ctx context.Context, options GetOptions) (Container, error)
295         ContainerList(ctx context.Context, options ListOptions) (ContainerList, error)
296         ContainerDelete(ctx context.Context, options DeleteOptions) (Container, error)
297         ContainerLock(ctx context.Context, options GetOptions) (Container, error)
298         ContainerUnlock(ctx context.Context, options GetOptions) (Container, error)
299         ContainerSSH(ctx context.Context, options ContainerSSHOptions) (ConnectionResponse, error)
300         ContainerGatewayTunnel(ctx context.Context, options ContainerGatewayTunnelOptions) (ConnectionResponse, error)
301         ContainerRequestCreate(ctx context.Context, options CreateOptions) (ContainerRequest, error)
302         ContainerRequestUpdate(ctx context.Context, options UpdateOptions) (ContainerRequest, error)
303         ContainerRequestGet(ctx context.Context, options GetOptions) (ContainerRequest, error)
304         ContainerRequestList(ctx context.Context, options ListOptions) (ContainerRequestList, error)
305         ContainerRequestDelete(ctx context.Context, options DeleteOptions) (ContainerRequest, error)
306         ContainerRequestLog(ctx context.Context, options ContainerLogOptions) (http.Handler, error)
307         GroupCreate(ctx context.Context, options CreateOptions) (Group, error)
308         GroupUpdate(ctx context.Context, options UpdateOptions) (Group, error)
309         GroupGet(ctx context.Context, options GetOptions) (Group, error)
310         GroupList(ctx context.Context, options ListOptions) (GroupList, error)
311         GroupContents(ctx context.Context, options GroupContentsOptions) (ObjectList, error)
312         GroupShared(ctx context.Context, options ListOptions) (GroupList, error)
313         GroupDelete(ctx context.Context, options DeleteOptions) (Group, error)
314         GroupTrash(ctx context.Context, options DeleteOptions) (Group, error)
315         GroupUntrash(ctx context.Context, options UntrashOptions) (Group, error)
316         LinkCreate(ctx context.Context, options CreateOptions) (Link, error)
317         LinkUpdate(ctx context.Context, options UpdateOptions) (Link, error)
318         LinkGet(ctx context.Context, options GetOptions) (Link, error)
319         LinkList(ctx context.Context, options ListOptions) (LinkList, error)
320         LinkDelete(ctx context.Context, options DeleteOptions) (Link, error)
321         LogCreate(ctx context.Context, options CreateOptions) (Log, error)
322         LogUpdate(ctx context.Context, options UpdateOptions) (Log, error)
323         LogGet(ctx context.Context, options GetOptions) (Log, error)
324         LogList(ctx context.Context, options ListOptions) (LogList, error)
325         LogDelete(ctx context.Context, options DeleteOptions) (Log, error)
326         SpecimenCreate(ctx context.Context, options CreateOptions) (Specimen, error)
327         SpecimenUpdate(ctx context.Context, options UpdateOptions) (Specimen, error)
328         SpecimenGet(ctx context.Context, options GetOptions) (Specimen, error)
329         SpecimenList(ctx context.Context, options ListOptions) (SpecimenList, error)
330         SpecimenDelete(ctx context.Context, options DeleteOptions) (Specimen, error)
331         SysTrashSweep(ctx context.Context, options struct{}) (struct{}, error)
332         UserCreate(ctx context.Context, options CreateOptions) (User, error)
333         UserUpdate(ctx context.Context, options UpdateOptions) (User, error)
334         UserMerge(ctx context.Context, options UserMergeOptions) (User, error)
335         UserActivate(ctx context.Context, options UserActivateOptions) (User, error)
336         UserSetup(ctx context.Context, options UserSetupOptions) (map[string]interface{}, error)
337         UserUnsetup(ctx context.Context, options GetOptions) (User, error)
338         UserGet(ctx context.Context, options GetOptions) (User, error)
339         UserGetCurrent(ctx context.Context, options GetOptions) (User, error)
340         UserGetSystem(ctx context.Context, options GetOptions) (User, error)
341         UserList(ctx context.Context, options ListOptions) (UserList, error)
342         UserDelete(ctx context.Context, options DeleteOptions) (User, error)
343         UserBatchUpdate(context.Context, UserBatchUpdateOptions) (UserList, error)
344         UserAuthenticate(ctx context.Context, options UserAuthenticateOptions) (APIClientAuthorization, error)
345         APIClientAuthorizationCurrent(ctx context.Context, options GetOptions) (APIClientAuthorization, error)
346         APIClientAuthorizationCreate(ctx context.Context, options CreateOptions) (APIClientAuthorization, error)
347         APIClientAuthorizationList(ctx context.Context, options ListOptions) (APIClientAuthorizationList, error)
348         APIClientAuthorizationDelete(ctx context.Context, options DeleteOptions) (APIClientAuthorization, error)
349         APIClientAuthorizationUpdate(ctx context.Context, options UpdateOptions) (APIClientAuthorization, error)
350         APIClientAuthorizationGet(ctx context.Context, options GetOptions) (APIClientAuthorization, error)
351         DiscoveryDocument(ctx context.Context) (DiscoveryDocument, error)
352 }