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