Merge branch '17944-backend-vocabulary-validation-rebased' into 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         EndpointUserActivate                  = APIEndpoint{"POST", "arvados/v1/users/{uuid}/activate", ""}
72         EndpointUserCreate                    = APIEndpoint{"POST", "arvados/v1/users", "user"}
73         EndpointUserCurrent                   = APIEndpoint{"GET", "arvados/v1/users/current", ""}
74         EndpointUserDelete                    = APIEndpoint{"DELETE", "arvados/v1/users/{uuid}", ""}
75         EndpointUserGet                       = APIEndpoint{"GET", "arvados/v1/users/{uuid}", ""}
76         EndpointUserGetCurrent                = APIEndpoint{"GET", "arvados/v1/users/current", ""}
77         EndpointUserGetSystem                 = APIEndpoint{"GET", "arvados/v1/users/system", ""}
78         EndpointUserList                      = APIEndpoint{"GET", "arvados/v1/users", ""}
79         EndpointUserMerge                     = APIEndpoint{"POST", "arvados/v1/users/merge", ""}
80         EndpointUserSetup                     = APIEndpoint{"POST", "arvados/v1/users/setup", "user"}
81         EndpointUserSystem                    = APIEndpoint{"GET", "arvados/v1/users/system", ""}
82         EndpointUserUnsetup                   = APIEndpoint{"POST", "arvados/v1/users/{uuid}/unsetup", ""}
83         EndpointUserUpdate                    = APIEndpoint{"PATCH", "arvados/v1/users/{uuid}", "user"}
84         EndpointUserBatchUpdate               = APIEndpoint{"PATCH", "arvados/v1/users/batch_update", ""}
85         EndpointUserAuthenticate              = APIEndpoint{"POST", "arvados/v1/users/authenticate", ""}
86         EndpointAPIClientAuthorizationCurrent = APIEndpoint{"GET", "arvados/v1/api_client_authorizations/current", ""}
87 )
88
89 type ContainerSSHOptions struct {
90         UUID          string `json:"uuid"`
91         DetachKeys    string `json:"detach_keys"`
92         LoginUsername string `json:"login_username"`
93 }
94
95 type ContainerSSHConnection struct {
96         Conn   net.Conn           `json:"-"`
97         Bufrw  *bufio.ReadWriter  `json:"-"`
98         Logger logrus.FieldLogger `json:"-"`
99 }
100
101 type GetOptions struct {
102         UUID         string   `json:"uuid,omitempty"`
103         Select       []string `json:"select"`
104         IncludeTrash bool     `json:"include_trash"`
105         ForwardedFor string   `json:"forwarded_for,omitempty"`
106         Remote       string   `json:"remote,omitempty"`
107 }
108
109 type UntrashOptions struct {
110         UUID             string `json:"uuid"`
111         EnsureUniqueName bool   `json:"ensure_unique_name"`
112 }
113
114 type ListOptions struct {
115         ClusterID          string                 `json:"cluster_id"`
116         Select             []string               `json:"select"`
117         Filters            []Filter               `json:"filters"`
118         Where              map[string]interface{} `json:"where"`
119         Limit              int64                  `json:"limit"`
120         Offset             int64                  `json:"offset"`
121         Order              []string               `json:"order"`
122         Distinct           bool                   `json:"distinct"`
123         Count              string                 `json:"count"`
124         IncludeTrash       bool                   `json:"include_trash"`
125         IncludeOldVersions bool                   `json:"include_old_versions"`
126         BypassFederation   bool                   `json:"bypass_federation"`
127         ForwardedFor       string                 `json:"forwarded_for,omitempty"`
128         Include            string                 `json:"include"`
129 }
130
131 type CreateOptions struct {
132         ClusterID        string                 `json:"cluster_id"`
133         EnsureUniqueName bool                   `json:"ensure_unique_name"`
134         Select           []string               `json:"select"`
135         Attrs            map[string]interface{} `json:"attrs"`
136 }
137
138 type UpdateOptions struct {
139         UUID             string                 `json:"uuid"`
140         Attrs            map[string]interface{} `json:"attrs"`
141         Select           []string               `json:"select"`
142         BypassFederation bool                   `json:"bypass_federation"`
143 }
144
145 type GroupContentsOptions struct {
146         ClusterID          string   `json:"cluster_id"`
147         UUID               string   `json:"uuid,omitempty"`
148         Select             []string `json:"select"`
149         Filters            []Filter `json:"filters"`
150         Limit              int64    `json:"limit"`
151         Offset             int64    `json:"offset"`
152         Order              []string `json:"order"`
153         Distinct           bool     `json:"distinct"`
154         Count              string   `json:"count"`
155         Include            string   `json:"include"`
156         Recursive          bool     `json:"recursive"`
157         IncludeTrash       bool     `json:"include_trash"`
158         IncludeOldVersions bool     `json:"include_old_versions"`
159         ExcludeHomeProject bool     `json:"exclude_home_project"`
160 }
161
162 type UserActivateOptions struct {
163         UUID string `json:"uuid"`
164 }
165
166 type UserSetupOptions struct {
167         UUID                  string                 `json:"uuid,omitempty"`
168         Email                 string                 `json:"email,omitempty"`
169         OpenIDPrefix          string                 `json:"openid_prefix,omitempty"`
170         RepoName              string                 `json:"repo_name,omitempty"`
171         VMUUID                string                 `json:"vm_uuid,omitempty"`
172         SendNotificationEmail bool                   `json:"send_notification_email,omitempty"`
173         Attrs                 map[string]interface{} `json:"attrs"`
174 }
175
176 type UserMergeOptions struct {
177         NewUserUUID       string `json:"new_user_uuid,omitempty"`
178         OldUserUUID       string `json:"old_user_uuid,omitempty"`
179         NewOwnerUUID      string `json:"new_owner_uuid,omitempty"`
180         NewUserToken      string `json:"new_user_token,omitempty"`
181         RedirectToNewUser bool   `json:"redirect_to_new_user"`
182 }
183
184 type UserBatchUpdateOptions struct {
185         Updates map[string]map[string]interface{} `json:"updates"`
186 }
187
188 type UserBatchUpdateResponse struct{}
189
190 type DeleteOptions struct {
191         UUID string `json:"uuid"`
192 }
193
194 type LoginOptions struct {
195         ReturnTo string `json:"return_to"`        // On success, redirect to this target with api_token=xxx query param
196         Remote   string `json:"remote,omitempty"` // Salt token for remote Cluster ID
197         Code     string `json:"code,omitempty"`   // OAuth2 callback code
198         State    string `json:"state,omitempty"`  // OAuth2 callback state
199 }
200
201 type UserAuthenticateOptions struct {
202         Username string `json:"username,omitempty"` // PAM username
203         Password string `json:"password,omitempty"` // PAM password
204 }
205
206 type LogoutOptions struct {
207         ReturnTo string `json:"return_to"` // Redirect to this URL after logging out
208 }
209
210 type BlockWriteOptions struct {
211         Hash           string
212         Data           []byte
213         Reader         io.Reader
214         DataSize       int // Must be set if Data is nil.
215         RequestID      string
216         StorageClasses []string
217         Replicas       int
218         Attempts       int
219 }
220
221 type BlockWriteResponse struct {
222         Locator  string
223         Replicas int
224 }
225
226 type API interface {
227         ConfigGet(ctx context.Context) (json.RawMessage, error)
228         VocabularyGet(ctx context.Context) (Vocabulary, error)
229         Login(ctx context.Context, options LoginOptions) (LoginResponse, error)
230         Logout(ctx context.Context, options LogoutOptions) (LogoutResponse, error)
231         CollectionCreate(ctx context.Context, options CreateOptions) (Collection, error)
232         CollectionUpdate(ctx context.Context, options UpdateOptions) (Collection, error)
233         CollectionGet(ctx context.Context, options GetOptions) (Collection, error)
234         CollectionList(ctx context.Context, options ListOptions) (CollectionList, error)
235         CollectionProvenance(ctx context.Context, options GetOptions) (map[string]interface{}, error)
236         CollectionUsedBy(ctx context.Context, options GetOptions) (map[string]interface{}, error)
237         CollectionDelete(ctx context.Context, options DeleteOptions) (Collection, error)
238         CollectionTrash(ctx context.Context, options DeleteOptions) (Collection, error)
239         CollectionUntrash(ctx context.Context, options UntrashOptions) (Collection, error)
240         ContainerCreate(ctx context.Context, options CreateOptions) (Container, error)
241         ContainerUpdate(ctx context.Context, options UpdateOptions) (Container, error)
242         ContainerGet(ctx context.Context, options GetOptions) (Container, error)
243         ContainerList(ctx context.Context, options ListOptions) (ContainerList, error)
244         ContainerDelete(ctx context.Context, options DeleteOptions) (Container, error)
245         ContainerLock(ctx context.Context, options GetOptions) (Container, error)
246         ContainerUnlock(ctx context.Context, options GetOptions) (Container, error)
247         ContainerSSH(ctx context.Context, options ContainerSSHOptions) (ContainerSSHConnection, error)
248         ContainerRequestCreate(ctx context.Context, options CreateOptions) (ContainerRequest, error)
249         ContainerRequestUpdate(ctx context.Context, options UpdateOptions) (ContainerRequest, error)
250         ContainerRequestGet(ctx context.Context, options GetOptions) (ContainerRequest, error)
251         ContainerRequestList(ctx context.Context, options ListOptions) (ContainerRequestList, error)
252         ContainerRequestDelete(ctx context.Context, options DeleteOptions) (ContainerRequest, error)
253         GroupCreate(ctx context.Context, options CreateOptions) (Group, error)
254         GroupUpdate(ctx context.Context, options UpdateOptions) (Group, error)
255         GroupGet(ctx context.Context, options GetOptions) (Group, error)
256         GroupList(ctx context.Context, options ListOptions) (GroupList, error)
257         GroupContents(ctx context.Context, options GroupContentsOptions) (ObjectList, error)
258         GroupShared(ctx context.Context, options ListOptions) (GroupList, error)
259         GroupDelete(ctx context.Context, options DeleteOptions) (Group, error)
260         GroupTrash(ctx context.Context, options DeleteOptions) (Group, error)
261         GroupUntrash(ctx context.Context, options UntrashOptions) (Group, error)
262         LinkCreate(ctx context.Context, options CreateOptions) (Link, error)
263         LinkUpdate(ctx context.Context, options UpdateOptions) (Link, error)
264         LinkGet(ctx context.Context, options GetOptions) (Link, error)
265         LinkList(ctx context.Context, options ListOptions) (LinkList, error)
266         LinkDelete(ctx context.Context, options DeleteOptions) (Link, error)
267         SpecimenCreate(ctx context.Context, options CreateOptions) (Specimen, error)
268         SpecimenUpdate(ctx context.Context, options UpdateOptions) (Specimen, error)
269         SpecimenGet(ctx context.Context, options GetOptions) (Specimen, error)
270         SpecimenList(ctx context.Context, options ListOptions) (SpecimenList, error)
271         SpecimenDelete(ctx context.Context, options DeleteOptions) (Specimen, error)
272         UserCreate(ctx context.Context, options CreateOptions) (User, error)
273         UserUpdate(ctx context.Context, options UpdateOptions) (User, error)
274         UserMerge(ctx context.Context, options UserMergeOptions) (User, error)
275         UserActivate(ctx context.Context, options UserActivateOptions) (User, error)
276         UserSetup(ctx context.Context, options UserSetupOptions) (map[string]interface{}, error)
277         UserUnsetup(ctx context.Context, options GetOptions) (User, error)
278         UserGet(ctx context.Context, options GetOptions) (User, error)
279         UserGetCurrent(ctx context.Context, options GetOptions) (User, error)
280         UserGetSystem(ctx context.Context, options GetOptions) (User, error)
281         UserList(ctx context.Context, options ListOptions) (UserList, error)
282         UserDelete(ctx context.Context, options DeleteOptions) (User, error)
283         UserBatchUpdate(context.Context, UserBatchUpdateOptions) (UserList, error)
284         UserAuthenticate(ctx context.Context, options UserAuthenticateOptions) (APIClientAuthorization, error)
285         APIClientAuthorizationCurrent(ctx context.Context, options GetOptions) (APIClientAuthorization, error)
286 }