summaryrefslogtreecommitdiffstats
path: root/lib/xdsconfig/configfile.go
blob: 27456e7984e624807333d19e65d4de24d006f988 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright (C) 2017-2018 "IoT.bzh"
 * Author Sebastien Douheret <sebastien@iot.bzh>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package xdsconfig

import (
	"encoding/json"
	"os"
	"path"

	common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib"
)

type SyncThingConf struct {
	BinDir     string `json:"binDir"`
	Home       string `json:"home"`
	GuiAddress string `json:"gui-address"`
	GuiAPIKey  string `json:"gui-apikey"`
}

type XDSServerConf struct {
	URL       string `json:"url"`
	ConnRetry int    `json:"connRetry"`

	// private/not exported fields
	ID            string `json:"-"`
	APIBaseURL    string `json:"-"`
	APIPartialURL string `json:"-"`
}

type FileConfig struct {
	HTTPPort    string          `json:"httpPort"`
	WebAppDir   string          `json:"webAppDir"`
	LogsDir     string          `json:"logsDir"`
	XDSAPIKey   string          `json:"xds-apikey"`
	ServersConf []XDSServerConf `json:"xdsServers"`
	SThgConf    *SyncThingConf  `json:"syncthing"`
}

// readGlobalConfig reads configuration from a config file.
// Order to determine which config file is used:
//  1/ from command line option: "--config myConfig.json"
//  2/ $HOME/.xds/agent/agent-config.json file
//  3/ /etc/xds/agent/agent-config.json file

func readGlobalConfig(c *Config, confFile string) error {

	var fd *os.File
	var fCfg = FileConfig{}

	searchIn := make([]string, 0, 3)
	if confFile != "" {
		searchIn = append(searchIn, confFile)
	}
	if homeDir := common.GetUserHome(); homeDir != "" {
		searchIn = append(searchIn, path.Join(homeDir, ".xds", "agent", "agent-config.json"))
	}

	searchIn = append(searchIn, "/etc/xds/agent/agent-config.json")

	var cFile *string
	for _, p := range searchIn {
		if _, err := os.Stat(p); err == nil {
			cFile = &p
			break
		}
	}
	if cFile == nil {
		c.Log.Infof("No config file found")
		// always resolved env vars even if no config file found!
		goto resVars
	}

	c.Log.Infof("Use config file: %s", *cFile)

	// TODO move on viper package to support comments in JSON and also
	// bind with flags (command line options)
	// see https://github.com/spf13/viper#working-with-flags

	fd, _ = os.Open(*cFile)
	defer func() {
		if fd != nil {
			fd.Close()
		}
	}()

	// Decode config file content and save it in a first variable
	if err := json.NewDecoder(fd).Decode(&fCfg); err != nil {
		return err
	}

	// Decode config file content and overwrite default settings
	fd.Seek(0, 0)
	json.NewDecoder(fd).Decode(&c.FileConf)

	// Disable Syncthing support when there is no syncthing field in config
	if fCfg.SThgConf == nil {
		c.FileConf.SThgConf = nil
	}

	// Support environment variables (IOW ${MY_ENV_VAR} syntax) in agent-config.json
resVars:
	vars := []*string{
		&c.FileConf.LogsDir,
		&c.FileConf.WebAppDir,
	}
	if c.FileConf.SThgConf != nil {
		vars = append(vars, &c.FileConf.SThgConf.Home,
			&c.FileConf.SThgConf.BinDir)
	}
	for _, field := range vars {
		var err error
		*field, err = common.ResolveEnvVar(*field)
		if err != nil {
			return err
		}
	}

	return nil
}