/
config.go
75 lines (63 loc) · 1.8 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
package cyqldog
import (
"bytes"
"html/template"
"os"
"strings"
"golang.org/x/xerrors"
yaml "gopkg.in/yaml.v2"
)
// Config represents the structure of the configuration file.
type Config struct {
// DB is a configuration of the database to connect.
DB DataSourceConfig `yaml:"data_source"`
// Notifiers are configurations of output plugins.
Notifiers NotifiersConfig `yaml:"notifiers"`
// Rules are a list of rules to monitor
Rules []Rule `yaml:"rules"`
}
// newConfig returns an instance of the Config.
func newConfig(filename string) (*Config, error) {
// Read bytes from file.
buf, err := os.ReadFile(filename)
if err != nil {
return nil, xerrors.Errorf("failed to read file: %s: %w", filename, err)
}
// Render envionment variables in the configuration file.
rendered, err := renderEnv(buf)
if err != nil {
return nil, err
}
// Parse yaml into Config.
c := Config{}
err = yaml.Unmarshal(rendered, &c)
if err != nil {
return nil, xerrors.Errorf("failed to parse yaml: %s: %w", filename, err)
}
return &c, nil
}
// envMap is a map of environment variables.
type envMap map[string]string
// newEnvMap returns a map of environment variables.
func newEnvMap() *envMap {
envs := make(envMap)
for _, e := range os.Environ() {
pair := strings.Split(e, "=")
envs[pair[0]] = pair[1]
}
return &envs
}
// renderEnv embeds environment variables with input buffer as a template.
func renderEnv(buf []byte) ([]byte, error) {
tmpl, err := template.New("env").Parse(string(buf))
if err != nil {
return []byte{}, xerrors.Errorf("failed to parse template: %v: %w", buf, err)
}
var rendered bytes.Buffer
envs := newEnvMap()
err = tmpl.Execute(&rendered, *envs)
if err != nil {
return []byte{}, xerrors.Errorf("failed to execute template: %v: %w", buf, err)
}
return rendered.Bytes(), nil
}