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