-
Notifications
You must be signed in to change notification settings - Fork 6
/
config.go
110 lines (101 loc) · 2.9 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
101
102
103
104
105
106
107
108
109
110
// Package config provides the definition of Config and a method
// to parse it from a []byte
package config
import (
"errors"
"fmt"
"io"
"os"
"reflect"
"github.com/davecgh/go-spew/spew"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
// RepoConfig stores config of each repo in a map
type RepoConfig map[string]interface{}
type JsonAPIConfig struct {
// The address that lug listens for JSON API
Address string
}
type LogStashConfig struct {
Address string
AdditionalFields map[string]interface{} `mapstructure:"additional_fields"`
}
// Config stores all configuration of lug
type Config struct {
// Interval between pollings in manager
Interval int
// LogLevel: 0-5 is acceptable
LogLevel log.Level
// ConcurrentLimit: how many worker can run at the same time
ConcurrentLimit int `mapstructure:"concurrent_limit"`
// LogStashConfig represents configurations for logstash
LogStashConfig LogStashConfig `mapstructure:"logstash"`
// ExporterAddr is the address to expose metrics, :8080 for default
ExporterAddr string `mapstructure:"exporter_address"`
// JsonAPIConfig specifies configuration of JSON restful API
JsonAPIConfig JsonAPIConfig `mapstructure:"json_api"`
// Worker sync checkpoint path
Checkpoint string `mapstructure:"checkpoint"`
// Config for each repo is represented as an array of RepoConfig. Nested structure is disallowed
Repos []RepoConfig
// A dummy section that will not be used in our program.
Dummy interface{} `mapstructure:"dummy"`
}
// CfgViper is the instance of config
var CfgViper *viper.Viper
func init() {
CfgViper = viper.New()
CfgViper.SetDefault("loglevel", 4)
CfgViper.SetDefault("json_api.address", ":7001")
CfgViper.SetDefault("exporter_address", ":8080")
CfgViper.SetDefault("concurrent_limit", 5)
}
// Parse creates config from a reader
func (c *Config) Parse(in io.Reader) (err error) {
CfgViper.SetConfigType("yaml")
err = CfgViper.ReadConfig(in)
if err != nil {
return err
}
err = CfgViper.UnmarshalExact(&c)
if err == nil {
if c.Interval < 0 {
return errors.New("Interval can't be negative")
}
if c.LogLevel < 0 || c.LogLevel > 5 {
return errors.New("loglevel must be 0-5")
}
if c.ConcurrentLimit <= 0 {
return errors.New("concurrent limit must be positive")
}
}
for _, repo := range c.Repos {
var removeKeys []string
for k, v := range repo {
t := reflect.TypeOf(v)
if t == nil {
continue
}
kind := t.Kind()
var invalidKinds = map[reflect.Kind]bool{
reflect.Array: true,
reflect.Map: true,
reflect.Slice: true,
reflect.Struct: true,
reflect.Interface: true,
}
if _, ok := invalidKinds[kind]; ok {
removeKeys = append(removeKeys, k)
_, err := fmt.Fprintln(os.Stderr, "nested property(e.g. arrays/maps) in Repos ignored: "+spew.Sdump(v))
if err != nil {
return err
}
}
}
for _, k := range removeKeys {
delete(repo, k)
}
}
return err
}