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