16736: Adds API.MaxTokenLifetime config knob.
[arvados.git] / sdk / go / arvados / config.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         "encoding/json"
9         "errors"
10         "fmt"
11         "net/url"
12         "os"
13
14         "git.arvados.org/arvados.git/sdk/go/config"
15 )
16
17 var DefaultConfigFile = func() string {
18         if path := os.Getenv("ARVADOS_CONFIG"); path != "" {
19                 return path
20         }
21         return "/etc/arvados/config.yml"
22 }()
23
24 type Config struct {
25         Clusters         map[string]Cluster
26         AutoReloadConfig bool
27 }
28
29 // GetConfig returns the current system config, loading it from
30 // configFile if needed.
31 func GetConfig(configFile string) (*Config, error) {
32         var cfg Config
33         err := config.LoadFile(&cfg, configFile)
34         return &cfg, err
35 }
36
37 // GetCluster returns the cluster ID and config for the given
38 // cluster, or the default/only configured cluster if clusterID is "".
39 func (sc *Config) GetCluster(clusterID string) (*Cluster, error) {
40         if clusterID == "" {
41                 if len(sc.Clusters) == 0 {
42                         return nil, fmt.Errorf("no clusters configured")
43                 } else if len(sc.Clusters) > 1 {
44                         return nil, fmt.Errorf("multiple clusters configured, cannot choose")
45                 } else {
46                         for id, cc := range sc.Clusters {
47                                 cc.ClusterID = id
48                                 return &cc, nil
49                         }
50                 }
51         }
52         cc, ok := sc.Clusters[clusterID]
53         if !ok {
54                 return nil, fmt.Errorf("cluster %q is not configured", clusterID)
55         }
56         cc.ClusterID = clusterID
57         return &cc, nil
58 }
59
60 type WebDAVCacheConfig struct {
61         TTL                  Duration
62         UUIDTTL              Duration
63         MaxBlockEntries      int
64         MaxCollectionEntries int
65         MaxCollectionBytes   int64
66         MaxPermissionEntries int
67         MaxUUIDEntries       int
68 }
69
70 type Cluster struct {
71         ClusterID       string `json:"-"`
72         ManagementToken string
73         SystemRootToken string
74         Services        Services
75         InstanceTypes   InstanceTypeMap
76         Containers      ContainersConfig
77         RemoteClusters  map[string]RemoteCluster
78         PostgreSQL      PostgreSQL
79
80         API struct {
81                 AsyncPermissionsUpdateInterval Duration
82                 DisabledAPIs                   StringSet
83                 MaxIndexDatabaseRead           int
84                 MaxItemsPerResponse            int
85                 MaxConcurrentRequests          int
86                 MaxKeepBlobBuffers             int
87                 MaxRequestAmplification        int
88                 MaxRequestSize                 int
89                 MaxTokenLifetime               Duration
90                 RequestTimeout                 Duration
91                 SendTimeout                    Duration
92                 WebsocketClientEventQueue      int
93                 WebsocketServerEventQueue      int
94                 KeepServiceRequestTimeout      Duration
95         }
96         AuditLogs struct {
97                 MaxAge             Duration
98                 MaxDeleteBatch     int
99                 UnloggedAttributes StringSet
100         }
101         Collections struct {
102                 BlobSigning              bool
103                 BlobSigningKey           string
104                 BlobSigningTTL           Duration
105                 BlobTrash                bool
106                 BlobTrashLifetime        Duration
107                 BlobTrashCheckInterval   Duration
108                 BlobTrashConcurrency     int
109                 BlobDeleteConcurrency    int
110                 BlobReplicateConcurrency int
111                 CollectionVersioning     bool
112                 DefaultTrashLifetime     Duration
113                 DefaultReplication       int
114                 ManagedProperties        map[string]struct {
115                         Value     interface{}
116                         Function  string
117                         Protected bool
118                 }
119                 PreserveVersionIfIdle        Duration
120                 TrashSweepInterval           Duration
121                 TrustAllContent              bool
122                 ForwardSlashNameSubstitution string
123                 S3FolderObjects              bool
124
125                 BlobMissingReport        string
126                 BalancePeriod            Duration
127                 BalanceCollectionBatch   int
128                 BalanceCollectionBuffers int
129                 BalanceTimeout           Duration
130
131                 WebDAVCache WebDAVCacheConfig
132         }
133         Git struct {
134                 GitCommand   string
135                 GitoliteHome string
136                 Repositories string
137         }
138         Login struct {
139                 LDAP struct {
140                         Enable             bool
141                         URL                URL
142                         StartTLS           bool
143                         InsecureTLS        bool
144                         StripDomain        string
145                         AppendDomain       string
146                         SearchAttribute    string
147                         SearchBindUser     string
148                         SearchBindPassword string
149                         SearchBase         string
150                         SearchFilters      string
151                         EmailAttribute     string
152                         UsernameAttribute  string
153                 }
154                 Google struct {
155                         Enable                          bool
156                         ClientID                        string
157                         ClientSecret                    string
158                         AlternateEmailAddresses         bool
159                         AuthenticationRequestParameters map[string]string
160                 }
161                 OpenIDConnect struct {
162                         Enable                          bool
163                         Issuer                          string
164                         ClientID                        string
165                         ClientSecret                    string
166                         EmailClaim                      string
167                         EmailVerifiedClaim              string
168                         UsernameClaim                   string
169                         AuthenticationRequestParameters map[string]string
170                 }
171                 PAM struct {
172                         Enable             bool
173                         Service            string
174                         DefaultEmailDomain string
175                 }
176                 SSO struct {
177                         Enable            bool
178                         ProviderAppID     string
179                         ProviderAppSecret string
180                 }
181                 Test struct {
182                         Enable bool
183                         Users  map[string]TestUser
184                 }
185                 LoginCluster       string
186                 RemoteTokenRefresh Duration
187                 TokenLifetime      Duration
188                 TrustedClients     map[string]struct{}
189         }
190         Mail struct {
191                 MailchimpAPIKey                string
192                 MailchimpListID                string
193                 SendUserSetupNotificationEmail bool
194                 IssueReporterEmailFrom         string
195                 IssueReporterEmailTo           string
196                 SupportEmailAddress            string
197                 EmailFrom                      string
198         }
199         SystemLogs struct {
200                 LogLevel                string
201                 Format                  string
202                 MaxRequestLogParamsSize int
203         }
204         TLS struct {
205                 Certificate string
206                 Key         string
207                 Insecure    bool
208         }
209         Users struct {
210                 AnonymousUserToken                    string
211                 AdminNotifierEmailFrom                string
212                 AutoAdminFirstUser                    bool
213                 AutoAdminUserWithEmail                string
214                 AutoSetupNewUsers                     bool
215                 AutoSetupNewUsersWithRepository       bool
216                 AutoSetupNewUsersWithVmUUID           string
217                 AutoSetupUsernameBlacklist            StringSet
218                 EmailSubjectPrefix                    string
219                 NewInactiveUserNotificationRecipients StringSet
220                 NewUserNotificationRecipients         StringSet
221                 NewUsersAreActive                     bool
222                 UserNotifierEmailFrom                 string
223                 UserProfileNotificationAddress        string
224                 PreferDomainForUsername               string
225                 UserSetupMailText                     string
226         }
227         Volumes   map[string]Volume
228         Workbench struct {
229                 ActivationContactLink            string
230                 APIClientConnectTimeout          Duration
231                 APIClientReceiveTimeout          Duration
232                 APIResponseCompression           bool
233                 ApplicationMimetypesWithViewIcon StringSet
234                 ArvadosDocsite                   string
235                 ArvadosPublicDataDocURL          string
236                 DefaultOpenIdPrefix              string
237                 EnableGettingStartedPopup        bool
238                 EnablePublicProjectsPage         bool
239                 FileViewersConfigURL             string
240                 LogViewerMaxBytes                ByteSize
241                 MultiSiteSearch                  string
242                 ProfilingEnabled                 bool
243                 Repositories                     bool
244                 RepositoryCache                  string
245                 RunningJobLogRecordsToFetch      int
246                 SecretKeyBase                    string
247                 ShowRecentCollectionsOnDashboard bool
248                 ShowUserAgreementInline          bool
249                 ShowUserNotifications            bool
250                 SiteName                         string
251                 Theme                            string
252                 UserProfileFormFields            map[string]struct {
253                         Type                 string
254                         FormFieldTitle       string
255                         FormFieldDescription string
256                         Required             bool
257                         Position             int
258                         Options              map[string]struct{}
259                 }
260                 UserProfileFormMessage string
261                 VocabularyURL          string
262                 WelcomePageHTML        string
263                 InactivePageHTML       string
264                 SSHHelpPageHTML        string
265                 SSHHelpHostSuffix      string
266                 IdleTimeout            Duration
267         }
268
269         ForceLegacyAPI14 bool
270 }
271
272 type Volume struct {
273         AccessViaHosts   map[URL]VolumeAccess
274         ReadOnly         bool
275         Replication      int
276         StorageClasses   map[string]bool
277         Driver           string
278         DriverParameters json.RawMessage
279 }
280
281 type S3VolumeDriverParameters struct {
282         IAMRole            string
283         AccessKey          string
284         SecretKey          string
285         Endpoint           string
286         Region             string
287         Bucket             string
288         LocationConstraint bool
289         V2Signature        bool
290         UseAWSS3v2Driver   bool
291         IndexPageSize      int
292         ConnectTimeout     Duration
293         ReadTimeout        Duration
294         RaceWindow         Duration
295         UnsafeDelete       bool
296 }
297
298 type AzureVolumeDriverParameters struct {
299         StorageAccountName   string
300         StorageAccountKey    string
301         StorageBaseURL       string
302         ContainerName        string
303         RequestTimeout       Duration
304         ListBlobsRetryDelay  Duration
305         ListBlobsMaxAttempts int
306 }
307
308 type DirectoryVolumeDriverParameters struct {
309         Root      string
310         Serialize bool
311 }
312
313 type VolumeAccess struct {
314         ReadOnly bool
315 }
316
317 type Services struct {
318         Composer       Service
319         Controller     Service
320         DispatchCloud  Service
321         GitHTTP        Service
322         GitSSH         Service
323         Health         Service
324         Keepbalance    Service
325         Keepproxy      Service
326         Keepstore      Service
327         RailsAPI       Service
328         SSO            Service
329         WebDAVDownload Service
330         WebDAV         Service
331         WebShell       Service
332         Websocket      Service
333         Workbench1     Service
334         Workbench2     Service
335 }
336
337 type Service struct {
338         InternalURLs map[URL]ServiceInstance
339         ExternalURL  URL
340 }
341
342 type TestUser struct {
343         Email    string
344         Password string
345 }
346
347 // URL is a url.URL that is also usable as a JSON key/value.
348 type URL url.URL
349
350 // UnmarshalText implements encoding.TextUnmarshaler so URL can be
351 // used as a JSON key/value.
352 func (su *URL) UnmarshalText(text []byte) error {
353         u, err := url.Parse(string(text))
354         if err == nil {
355                 *su = URL(*u)
356                 if su.Path == "" && su.Host != "" {
357                         // http://example really means http://example/
358                         su.Path = "/"
359                 }
360         }
361         return err
362 }
363
364 func (su URL) MarshalText() ([]byte, error) {
365         return []byte(fmt.Sprintf("%s", (*url.URL)(&su).String())), nil
366 }
367
368 func (su URL) String() string {
369         return (*url.URL)(&su).String()
370 }
371
372 type ServiceInstance struct {
373         Rendezvous string `json:",omitempty"`
374 }
375
376 type PostgreSQL struct {
377         Connection     PostgreSQLConnection
378         ConnectionPool int
379 }
380
381 type PostgreSQLConnection map[string]string
382
383 type RemoteCluster struct {
384         Host          string
385         Proxy         bool
386         Scheme        string
387         Insecure      bool
388         ActivateUsers bool
389 }
390
391 type InstanceType struct {
392         Name            string
393         ProviderType    string
394         VCPUs           int
395         RAM             ByteSize
396         Scratch         ByteSize
397         IncludedScratch ByteSize
398         AddedScratch    ByteSize
399         Price           float64
400         Preemptible     bool
401 }
402
403 type ContainersConfig struct {
404         CloudVMs                    CloudVMsConfig
405         CrunchRunCommand            string
406         CrunchRunArgumentsList      []string
407         DefaultKeepCacheRAM         ByteSize
408         DispatchPrivateKey          string
409         LogReuseDecisions           bool
410         MaxComputeVMs               int
411         MaxDispatchAttempts         int
412         MaxRetryAttempts            int
413         MinRetryPeriod              Duration
414         ReserveExtraRAM             ByteSize
415         StaleLockTimeout            Duration
416         SupportedDockerImageFormats StringSet
417         UsePreemptibleInstances     bool
418
419         JobsAPI struct {
420                 Enable         string
421                 GitInternalDir string
422         }
423         Logging struct {
424                 MaxAge                       Duration
425                 LogBytesPerEvent             int
426                 LogSecondsBetweenEvents      Duration
427                 LogThrottlePeriod            Duration
428                 LogThrottleBytes             int
429                 LogThrottleLines             int
430                 LimitLogBytesPerJob          int
431                 LogPartialLineThrottlePeriod Duration
432                 LogUpdatePeriod              Duration
433                 LogUpdateSize                ByteSize
434         }
435         ShellAccess struct {
436                 Admin bool
437                 User  bool
438         }
439         SLURM struct {
440                 PrioritySpread             int64
441                 SbatchArgumentsList        []string
442                 SbatchEnvironmentVariables map[string]string
443                 Managed                    struct {
444                         DNSServerConfDir       string
445                         DNSServerConfTemplate  string
446                         DNSServerReloadCommand string
447                         DNSServerUpdateCommand string
448                         ComputeNodeDomain      string
449                         ComputeNodeNameservers StringSet
450                         AssignNodeHostname     string
451                 }
452         }
453 }
454
455 type CloudVMsConfig struct {
456         Enable bool
457
458         BootProbeCommand               string
459         DeployRunnerBinary             string
460         ImageID                        string
461         MaxCloudOpsPerSecond           int
462         MaxProbesPerSecond             int
463         MaxConcurrentInstanceCreateOps int
464         PollInterval                   Duration
465         ProbeInterval                  Duration
466         SSHPort                        string
467         SyncInterval                   Duration
468         TimeoutBooting                 Duration
469         TimeoutIdle                    Duration
470         TimeoutProbe                   Duration
471         TimeoutShutdown                Duration
472         TimeoutSignal                  Duration
473         TimeoutStaleRunLock            Duration
474         TimeoutTERM                    Duration
475         ResourceTags                   map[string]string
476         TagKeyPrefix                   string
477
478         Driver           string
479         DriverParameters json.RawMessage
480 }
481
482 type InstanceTypeMap map[string]InstanceType
483
484 var errDuplicateInstanceTypeName = errors.New("duplicate instance type name")
485
486 // UnmarshalJSON handles old config files that provide an array of
487 // instance types instead of a hash.
488 func (it *InstanceTypeMap) UnmarshalJSON(data []byte) error {
489         fixup := func(t InstanceType) (InstanceType, error) {
490                 if t.ProviderType == "" {
491                         t.ProviderType = t.Name
492                 }
493                 if t.Scratch == 0 {
494                         t.Scratch = t.IncludedScratch + t.AddedScratch
495                 } else if t.AddedScratch == 0 {
496                         t.AddedScratch = t.Scratch - t.IncludedScratch
497                 } else if t.IncludedScratch == 0 {
498                         t.IncludedScratch = t.Scratch - t.AddedScratch
499                 }
500
501                 if t.Scratch != (t.IncludedScratch + t.AddedScratch) {
502                         return t, fmt.Errorf("InstanceType %q: Scratch != (IncludedScratch + AddedScratch)", t.Name)
503                 }
504                 return t, nil
505         }
506
507         if len(data) > 0 && data[0] == '[' {
508                 var arr []InstanceType
509                 err := json.Unmarshal(data, &arr)
510                 if err != nil {
511                         return err
512                 }
513                 if len(arr) == 0 {
514                         *it = nil
515                         return nil
516                 }
517                 *it = make(map[string]InstanceType, len(arr))
518                 for _, t := range arr {
519                         if _, ok := (*it)[t.Name]; ok {
520                                 return errDuplicateInstanceTypeName
521                         }
522                         t, err := fixup(t)
523                         if err != nil {
524                                 return err
525                         }
526                         (*it)[t.Name] = t
527                 }
528                 return nil
529         }
530         var hash map[string]InstanceType
531         err := json.Unmarshal(data, &hash)
532         if err != nil {
533                 return err
534         }
535         // Fill in Name field (and ProviderType field, if not
536         // specified) using hash key.
537         *it = InstanceTypeMap(hash)
538         for name, t := range *it {
539                 t.Name = name
540                 t, err := fixup(t)
541                 if err != nil {
542                         return err
543                 }
544                 (*it)[name] = t
545         }
546         return nil
547 }
548
549 type StringSet map[string]struct{}
550
551 // UnmarshalJSON handles old config files that provide an array of
552 // instance types instead of a hash.
553 func (ss *StringSet) UnmarshalJSON(data []byte) error {
554         if len(data) > 0 && data[0] == '[' {
555                 var arr []string
556                 err := json.Unmarshal(data, &arr)
557                 if err != nil {
558                         return err
559                 }
560                 if len(arr) == 0 {
561                         *ss = nil
562                         return nil
563                 }
564                 *ss = make(map[string]struct{}, len(arr))
565                 for _, t := range arr {
566                         (*ss)[t] = struct{}{}
567                 }
568                 return nil
569         }
570         var hash map[string]struct{}
571         err := json.Unmarshal(data, &hash)
572         if err != nil {
573                 return err
574         }
575         *ss = make(map[string]struct{}, len(hash))
576         for t := range hash {
577                 (*ss)[t] = struct{}{}
578         }
579
580         return nil
581 }
582
583 type ServiceName string
584
585 const (
586         ServiceNameRailsAPI      ServiceName = "arvados-api-server"
587         ServiceNameController    ServiceName = "arvados-controller"
588         ServiceNameDispatchCloud ServiceName = "arvados-dispatch-cloud"
589         ServiceNameHealth        ServiceName = "arvados-health"
590         ServiceNameWorkbench1    ServiceName = "arvados-workbench1"
591         ServiceNameWorkbench2    ServiceName = "arvados-workbench2"
592         ServiceNameWebsocket     ServiceName = "arvados-ws"
593         ServiceNameKeepbalance   ServiceName = "keep-balance"
594         ServiceNameKeepweb       ServiceName = "keep-web"
595         ServiceNameKeepproxy     ServiceName = "keepproxy"
596         ServiceNameKeepstore     ServiceName = "keepstore"
597 )
598
599 // Map returns all services as a map, suitable for iterating over all
600 // services or looking up a service by name.
601 func (svcs Services) Map() map[ServiceName]Service {
602         return map[ServiceName]Service{
603                 ServiceNameRailsAPI:      svcs.RailsAPI,
604                 ServiceNameController:    svcs.Controller,
605                 ServiceNameDispatchCloud: svcs.DispatchCloud,
606                 ServiceNameHealth:        svcs.Health,
607                 ServiceNameWorkbench1:    svcs.Workbench1,
608                 ServiceNameWorkbench2:    svcs.Workbench2,
609                 ServiceNameWebsocket:     svcs.Websocket,
610                 ServiceNameKeepbalance:   svcs.Keepbalance,
611                 ServiceNameKeepweb:       svcs.WebDAV,
612                 ServiceNameKeepproxy:     svcs.Keepproxy,
613                 ServiceNameKeepstore:     svcs.Keepstore,
614         }
615 }