/
config.go
100 lines (84 loc) · 2.27 KB
/
config.go
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
package main
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/url"
"os"
"path/filepath"
"github.com/naoina/toml"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)
type unmarshal func([]byte, interface{}) error
func findAndLoadConfig() (map[string]*config, error) {
home, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("error looking for user home (maybe specify config file): %w", err)
}
configDir := filepath.Join(home, ".epithet")
for _, ext := range []string{"toml", "yaml", "yml", "json"} {
maybe := filepath.Join(configDir, fmt.Sprintf("agent.%s", ext))
_, err := os.Stat(maybe)
if err != nil {
continue
}
log.Infof("using config file %s", maybe)
return loadConfigFile(maybe)
}
return nil, errors.New("no config file found")
}
func loadConfigFile(path string) (map[string]*config, error) {
body, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("unable to load config file: %w", err)
}
ext := filepath.Ext(path)
switch ext {
case ".yaml":
return parse(yaml.Unmarshal, body)
case ".yml":
return parse(yaml.Unmarshal, body)
case ".toml":
return parse(toml.Unmarshal, body)
case ".json":
return parse(json.Unmarshal, body)
default:
return nil, fmt.Errorf("unknown config file type '%s'", ext)
}
}
func parse(un unmarshal, body []byte) (map[string]*config, error) {
agents := map[string]*config{}
if err := un(body, &agents); err != nil {
return nil, err
}
for name, cfg := range agents {
err := cfg.init(name)
if err != nil {
return nil, err
}
}
return agents, nil
}
type config struct {
CA string `json:"ca_url" yaml:"ca_url" toml:"ca_url"`
AgentSock string `json:"agent_sock" yaml:"agent_sock" toml:"agent_sock"`
ControlSock string `json:"control_sock" yaml:"control_sock" toml:"control_sock"`
Hooks map[string]string `json:"hooks" yaml:"hooks" toml:"hooks"`
Name string
}
func (c *config) init(name string) error {
c.Name = name
if c.AgentSock == "" {
c.AgentSock = fmt.Sprintf("~/.epithet/%s.agent.sock", name)
}
if c.ControlSock == "" {
c.ControlSock = fmt.Sprintf("~/.epithet/%s.control.sock", name)
}
_, err := url.Parse(c.CA)
if err != nil {
return fmt.Errorf("invalid ca_url: %w", err)
}
return nil
}