Added api to list and reconnect a XDS-Server.
[src/xds/xds-agent.git] / lib / xdsconfig / configfile.go
1 /*
2  * Copyright (C) 2017-2018 "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/golib"
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 FileConfig struct {
47         HTTPPort    string          `json:"httpPort"`
48         WebAppDir   string          `json:"webAppDir"`
49         LogsDir     string          `json:"logsDir"`
50         XDSAPIKey   string          `json:"xds-apikey"`
51         ServersConf []XDSServerConf `json:"xdsServers"`
52         SThgConf    *SyncThingConf  `json:"syncthing"`
53 }
54
55 // readGlobalConfig reads configuration from a config file.
56 // Order to determine which config file is used:
57 //  1/ from command line option: "--config myConfig.json"
58 //  2/ $HOME/.xds/agent/agent-config.json file
59 //  3/ /etc/xds/agent/agent-config.json file
60
61 func readGlobalConfig(c *Config, confFile string) error {
62
63         var fd *os.File
64         var fCfg = FileConfig{}
65
66         searchIn := make([]string, 0, 3)
67         if confFile != "" {
68                 searchIn = append(searchIn, confFile)
69         }
70         if homeDir := common.GetUserHome(); homeDir != "" {
71                 searchIn = append(searchIn, path.Join(homeDir, ".xds", "agent", "agent-config.json"))
72         }
73
74         searchIn = append(searchIn, "/etc/xds/agent/agent-config.json")
75
76         var cFile *string
77         for _, p := range searchIn {
78                 if _, err := os.Stat(p); err == nil {
79                         cFile = &p
80                         break
81                 }
82         }
83         if cFile == nil {
84                 c.Log.Infof("No config file found")
85                 // always resolved env vars even if no config file found!
86                 goto resVars
87         }
88
89         c.Log.Infof("Use config file: %s", *cFile)
90
91         // TODO move on viper package to support comments in JSON and also
92         // bind with flags (command line options)
93         // see https://github.com/spf13/viper#working-with-flags
94
95         fd, _ = os.Open(*cFile)
96         defer func() {
97                 if fd != nil {
98                         fd.Close()
99                 }
100         }()
101
102         // Decode config file content and save it in a first variable
103         if err := json.NewDecoder(fd).Decode(&fCfg); err != nil {
104                 return err
105         }
106
107         // Decode config file content and overwrite default settings
108         fd.Seek(0, 0)
109         json.NewDecoder(fd).Decode(&c.FileConf)
110
111         // Disable Syncthing support when there is no syncthing field in config
112         if fCfg.SThgConf == nil {
113                 c.FileConf.SThgConf = nil
114         }
115
116         // Support environment variables (IOW ${MY_ENV_VAR} syntax) in agent-config.json
117 resVars:
118         vars := []*string{
119                 &c.FileConf.LogsDir,
120                 &c.FileConf.WebAppDir,
121         }
122         if c.FileConf.SThgConf != nil {
123                 vars = append(vars, &c.FileConf.SThgConf.Home,
124                         &c.FileConf.SThgConf.BinDir)
125         }
126         for _, field := range vars {
127                 var err error
128                 *field, err = common.ResolveEnvVar(*field)
129                 if err != nil {
130                         return err
131                 }
132         }
133
134         return nil
135 }