Add LowCollector & rename Supervisor to Monitoring
[src/xds/xds-agent.git] / lib / xdsconfig / configfile.go
1 /*
2  * Copyright (C) 2017-2019 "IoT.bzh"
3  * Author Sebastien Douheret <sebastien@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package xdsconfig
19
20 import (
21         "encoding/json"
22         "os"
23         "path"
24
25         common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git"
26 )
27
28 type SyncThingConf struct {
29         BinDir     string `json:"binDir"`
30         Home       string `json:"home"`
31         GuiAddress string `json:"gui-address"`
32         GuiAPIKey  string `json:"gui-apikey"`
33 }
34
35 type XDSServerConf struct {
36         URL       string `json:"url"`
37         ConnRetry int    `json:"connRetry"`
38
39         // private/not exported fields
40         ID            string `json:"-"`
41         URLIndex      string `json:"-"`
42         APIBaseURL    string `json:"-"`
43         APIPartialURL string `json:"-"`
44 }
45
46 type XDSMonitoringConf struct {
47         URL       string `json:"url"`
48         ConnRetry int    `json:"connRetry"`
49 }
50
51 type XDSLowCollectorConf struct {
52         URL       string `json:"url"`
53         ConnRetry int    `json:"connRetry"`
54 }
55
56 type ProfileConfT struct {
57         XDSMonitoring   XDSMonitoringConf   `json:"xdsMonitoring"`
58         XDSLowCollector XDSLowCollectorConf `json:"xdsLowCollector"`
59 }
60
61 type FileConfig struct {
62         HTTPPort    string          `json:"httpPort"`
63         WebAppDir   string          `json:"webAppDir"`
64         LogsDir     string          `json:"logsDir"`
65         XDSAPIKey   string          `json:"xds-apikey"`
66         ServersConf []XDSServerConf `json:"xdsServers"`
67         SThgConf    *SyncThingConf  `json:"syncthing"`
68         ProfileConf ProfileConfT    `json:"profileConf"`
69 }
70
71 // readGlobalConfig reads configuration from a config file.
72 // Order to determine which config file is used:
73 //  1/ from command line option: "--config myConfig.json"
74 //  2/ $HOME/.xds/agent/agent-config.json file
75 //  3/ /etc/xds/agent/agent-config.json file
76
77 func readGlobalConfig(c *Config, confFile string) error {
78
79         var fd *os.File
80         var fCfg = FileConfig{}
81
82         searchIn := make([]string, 0, 3)
83         if confFile != "" {
84                 searchIn = append(searchIn, confFile)
85         }
86         if homeDir := common.GetUserHome(); homeDir != "" {
87                 searchIn = append(searchIn, path.Join(homeDir, ".xds", "agent", "agent-config.json"))
88         }
89
90         searchIn = append(searchIn, "/etc/xds/agent/agent-config.json")
91
92         var cFile *string
93         for _, p := range searchIn {
94                 if _, err := os.Stat(p); err == nil {
95                         cFile = &p
96                         break
97                 }
98         }
99         if cFile == nil {
100                 c.Log.Infof("No config file found")
101                 // always resolved env vars even if no config file found!
102                 goto resVars
103         }
104
105         c.Log.Infof("Use config file: %s", *cFile)
106
107         // TODO move on viper package to support comments in JSON and also
108         // bind with flags (command line options)
109         // see https://github.com/spf13/viper#working-with-flags
110
111         fd, _ = os.Open(*cFile)
112         defer func() {
113                 if fd != nil {
114                         fd.Close()
115                 }
116         }()
117
118         // Decode config file content and save it in a first variable
119         if err := json.NewDecoder(fd).Decode(&fCfg); err != nil {
120                 return err
121         }
122
123         // Decode config file content and overwrite default settings
124         fd.Seek(0, 0)
125         json.NewDecoder(fd).Decode(&c.FileConf)
126
127         // Disable Syncthing support when there is no syncthing field in config
128         if fCfg.SThgConf == nil {
129                 c.FileConf.SThgConf = nil
130         }
131
132         // Support environment variables (IOW ${MY_ENV_VAR} syntax) in agent-config.json
133 resVars:
134         vars := []*string{
135                 &c.FileConf.LogsDir,
136                 &c.FileConf.WebAppDir,
137         }
138         if c.FileConf.SThgConf != nil {
139                 vars = append(vars, &c.FileConf.SThgConf.Home,
140                         &c.FileConf.SThgConf.BinDir)
141         }
142         for _, field := range vars {
143                 var err error
144                 *field, err = common.ResolveEnvVar(*field)
145                 if err != nil {
146                         return err
147                 }
148         }
149
150         return nil
151 }