13493: Test OPTIONS method.
[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         "fmt"
9         "os"
10
11         "git.curoverse.com/arvados.git/sdk/go/config"
12 )
13
14 const DefaultConfigFile = "/etc/arvados/config.yml"
15
16 type Config struct {
17         Clusters map[string]Cluster
18 }
19
20 // GetConfig returns the current system config, loading it from
21 // configFile if needed.
22 func GetConfig(configFile string) (*Config, error) {
23         var cfg Config
24         err := config.LoadFile(&cfg, configFile)
25         return &cfg, err
26 }
27
28 // GetCluster returns the cluster ID and config for the given
29 // cluster, or the default/only configured cluster if clusterID is "".
30 func (sc *Config) GetCluster(clusterID string) (*Cluster, error) {
31         if clusterID == "" {
32                 if len(sc.Clusters) == 0 {
33                         return nil, fmt.Errorf("no clusters configured")
34                 } else if len(sc.Clusters) > 1 {
35                         return nil, fmt.Errorf("multiple clusters configured, cannot choose")
36                 } else {
37                         for id, cc := range sc.Clusters {
38                                 cc.ClusterID = id
39                                 return &cc, nil
40                         }
41                 }
42         }
43         if cc, ok := sc.Clusters[clusterID]; !ok {
44                 return nil, fmt.Errorf("cluster %q is not configured", clusterID)
45         } else {
46                 cc.ClusterID = clusterID
47                 return &cc, nil
48         }
49 }
50
51 type Cluster struct {
52         ClusterID          string `json:"-"`
53         ManagementToken    string
54         NodeProfiles       map[string]NodeProfile
55         InstanceTypes      []InstanceType
56         HTTPRequestTimeout Duration
57         RemoteClusters     map[string]RemoteCluster
58         PostgreSQL         PostgreSQL
59 }
60
61 type PostgreSQL struct {
62         Connection     PostgreSQLConnection
63         ConnectionPool int
64 }
65
66 type PostgreSQLConnection map[string]string
67
68 type RemoteCluster struct {
69         // API endpoint host or host:port; default is {id}.arvadosapi.com
70         Host string
71         // Perform a proxy request when a local client requests an
72         // object belonging to this remote.
73         Proxy bool
74         // Scheme, default "https". Can be set to "http" for testing.
75         Scheme string
76         // Disable TLS verify. Can be set to true for testing.
77         Insecure bool
78 }
79
80 type InstanceType struct {
81         Name         string
82         ProviderType string
83         VCPUs        int
84         RAM          int64
85         Scratch      int64
86         Price        float64
87         Preemptible  bool
88 }
89
90 // GetNodeProfile returns a NodeProfile for the given hostname. An
91 // error is returned if the appropriate configuration can't be
92 // determined (e.g., this does not appear to be a system node). If
93 // node is empty, use the OS-reported hostname.
94 func (cc *Cluster) GetNodeProfile(node string) (*NodeProfile, error) {
95         if node == "" {
96                 hostname, err := os.Hostname()
97                 if err != nil {
98                         return nil, err
99                 }
100                 node = hostname
101         }
102         if cfg, ok := cc.NodeProfiles[node]; ok {
103                 return &cfg, nil
104         }
105         // If node is not listed, but "*" gives a default system node
106         // config, use the default config.
107         if cfg, ok := cc.NodeProfiles["*"]; ok {
108                 return &cfg, nil
109         }
110         return nil, fmt.Errorf("config does not provision host %q as a system node", node)
111 }
112
113 type NodeProfile struct {
114         Controller  SystemServiceInstance `json:"arvados-controller"`
115         Health      SystemServiceInstance `json:"arvados-health"`
116         Keepproxy   SystemServiceInstance `json:"keepproxy"`
117         Keepstore   SystemServiceInstance `json:"keepstore"`
118         Keepweb     SystemServiceInstance `json:"keep-web"`
119         Nodemanager SystemServiceInstance `json:"arvados-node-manager"`
120         RailsAPI    SystemServiceInstance `json:"arvados-api-server"`
121         Websocket   SystemServiceInstance `json:"arvados-ws"`
122         Workbench   SystemServiceInstance `json:"arvados-workbench"`
123 }
124
125 type ServiceName string
126
127 const (
128         ServiceNameRailsAPI    ServiceName = "arvados-api-server"
129         ServiceNameController  ServiceName = "arvados-controller"
130         ServiceNameNodemanager ServiceName = "arvados-node-manager"
131         ServiceNameWorkbench   ServiceName = "arvados-workbench"
132         ServiceNameWebsocket   ServiceName = "arvados-ws"
133         ServiceNameKeepweb     ServiceName = "keep-web"
134         ServiceNameKeepproxy   ServiceName = "keepproxy"
135         ServiceNameKeepstore   ServiceName = "keepstore"
136 )
137
138 // ServicePorts returns the configured listening address (or "" if
139 // disabled) for each service on the node.
140 func (np *NodeProfile) ServicePorts() map[ServiceName]string {
141         return map[ServiceName]string{
142                 ServiceNameRailsAPI:    np.RailsAPI.Listen,
143                 ServiceNameController:  np.Controller.Listen,
144                 ServiceNameNodemanager: np.Nodemanager.Listen,
145                 ServiceNameWorkbench:   np.Workbench.Listen,
146                 ServiceNameWebsocket:   np.Websocket.Listen,
147                 ServiceNameKeepweb:     np.Keepweb.Listen,
148                 ServiceNameKeepproxy:   np.Keepproxy.Listen,
149                 ServiceNameKeepstore:   np.Keepstore.Listen,
150         }
151 }
152
153 type SystemServiceInstance struct {
154         Listen   string
155         TLS      bool
156         Insecure bool
157 }