12260: Fix remote ping auth. Make server work.
[arvados.git] / sdk / go / arvados / config.go
1 package arvados
2
3 import (
4         "fmt"
5         "os"
6         "strings"
7
8         "git.curoverse.com/arvados.git/sdk/go/config"
9 )
10
11 type Config struct {
12         Clusters map[string]Cluster
13 }
14
15 // GetConfig returns the current system config, loading it from
16 // /etc if needed.
17 func GetConfig() (*Config, error) {
18         var cfg Config
19         err := config.LoadFile(&cfg, "/etc/arvados/config.yml")
20         return &cfg, err
21 }
22
23 // GetCluster returns the cluster ID and config for the given
24 // cluster, or the default/only configured cluster if clusterID is "".
25 func (sc *Config) GetCluster(clusterID string) (*Cluster, error) {
26         if clusterID == "" {
27                 if len(sc.Clusters) == 0 {
28                         return nil, fmt.Errorf("no clusters configured")
29                 } else if len(sc.Clusters) > 1 {
30                         return nil, fmt.Errorf("multiple clusters configured, cannot choose")
31                 } else {
32                         for id, cc := range sc.Clusters {
33                                 cc.ClusterID = id
34                                 return &cc, nil
35                         }
36                 }
37         }
38         if cc, ok := sc.Clusters[clusterID]; !ok {
39                 return nil, fmt.Errorf("cluster %q is not configured", clusterID)
40         } else {
41                 cc.ClusterID = clusterID
42                 return &cc, nil
43         }
44 }
45
46 type Cluster struct {
47         ClusterID       string `json:"-"`
48         ManagementToken string
49         SystemNodes     map[string]SystemNode
50 }
51
52 // GetThisSystemNodeConfig returns a SystemNode for the node we're
53 // running on right now.
54 func (cc *Cluster) GetThisSystemNode() (*SystemNode, error) {
55         hostname, err := os.Hostname()
56         if err != nil {
57                 return nil, err
58         }
59         return cc.GetSystemNode(hostname)
60 }
61
62 // GetSystemNodeConfig returns a NodeConfig for the given node. An
63 // error is returned if the appropriate configuration can't be
64 // determined (e.g., this does not appear to be a system node).
65 func (cc *Cluster) GetSystemNode(node string) (*SystemNode, error) {
66         // Generally node is "a.b.ca", use the first of {"a.b.ca",
67         // "a.b", "a"} that has an entry in SystemNodes.
68         labels := strings.Split(node, ".")
69         for j := len(labels); j > 0; j-- {
70                 hostpart := strings.Join(labels[:j], ".")
71                 if cfg, ok := cc.SystemNodes[hostpart]; ok {
72                         return &cfg, nil
73                 }
74         }
75         // If node is not listed, but "*" gives a default system node
76         // config, use the default config.
77         if cfg, ok := cc.SystemNodes["*"]; ok {
78                 return &cfg, nil
79         }
80         return nil, fmt.Errorf("config does not provision host %q as a system node", node)
81 }
82
83 type SystemNode struct {
84         Health    Health
85         Keepstore Keepstore
86 }
87
88 type Health struct {
89         Listen string
90 }
91
92 type Keepstore struct {
93         Listen string
94 }