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