-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
129 lines (116 loc) · 3.32 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package main
import (
"fmt"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"io/ioutil"
"net/url"
"sigs.k8s.io/yaml"
"sort"
"strings"
)
type Config struct {
LogLevel string `json:"logLevel"`
LogForceColors bool `json:"logForceColors"`
Debug bool `json:"debug"`
AccessLog bool `json:"accessLog"`
Manage *ManageConfig `json:"manage"`
Statistic *StatisticConfig `json:"statistic"`
Upstreams []string `json:"upstreams"`
K8sServiceDiscovery *K8sSDConfig `json:"k8sServiceDiscovery"`
Listen string `json:"listen"`
Path string `json:"path"`
KeepAlive string `json:"keepAlive"`
UpstreamRequestTimeout Duration `json:"upstreamRequestTimeout"`
ReadTimeout Duration `json:"readTimeout"`
WriteTimeout Duration `json:"writeTimeout"`
IdleTimeout Duration `json:"idleTimeout"`
ErrFor Duration `json:"errFor"`
CacheConfigs []*CacheConfig `json:"cacheConfigs"`
}
type ManageConfig struct {
Listen string `json:"listen"`
Path string `json:"path"`
MetricsPath string `json:"metricsPath"`
}
type CacheConfig struct {
Methods []string `json:"methods"`
For Duration `json:"for"`
ErrFor Duration `json:"errFor"`
}
func (cc *CacheConfig) Sort() {
sort.Strings(cc.Methods)
}
type K8sSDConfig struct {
Namespace string `json:"namespace"`
Name string `json:"name"`
Port int `json:"port"`
}
type StatisticConfig struct {
Enabled bool `json:"enabled"`
}
func LoadConfig(path string) (conf *Config, err error) {
content, err := ioutil.ReadFile(path)
if err != nil {
return
}
conf = new(Config)
err = yaml.UnmarshalStrict(content, conf)
for _, c := range conf.CacheConfigs {
c.Sort()
}
return
}
func (c *Config) Search(method string) *CacheConfig {
for _, cc := range c.CacheConfigs {
i := sort.SearchStrings(cc.Methods, method)
if i < len(cc.Methods) && cc.Methods[i] == method {
return cc
}
}
return nil
}
func validateListen(l string) error {
if strings.Index(l, "://") == -1 {
l = "http://" + l
}
u, err := url.Parse(l)
if err != nil {
return err
}
if u.Hostname() == "" || u.Port() == "" {
return errors.New("Invalid listen address")
}
return nil
}
func (c Config) Validate() error {
err := validateListen(c.Listen)
if err != nil {
return errors.Wrap(err, "config.listen address is not valid")
}
if !strings.HasPrefix(c.Path, "/") {
return errors.New("config.path is not valid")
}
if c.Manage.Path != "" && !strings.HasPrefix(c.Manage.Path, "/") {
return errors.New("config.manage.Path is not valid")
}
if c.Manage.MetricsPath != "" && !strings.HasPrefix(c.Manage.MetricsPath, "/") {
return errors.New("config.manage.metricsPath is not valid")
}
if len(c.Upstreams) == 0 {
return errors.New("config.upstreams is empty")
}
return nil
}
func (c Config) MustValidate() {
if err := c.Validate(); err != nil {
log.WithError(err).Fatal("invalid config")
}
}
func ParseUpstream(addr string) string {
u, err := url.Parse(addr)
if err != nil {
log.Fatal(errors.Wrap(err, fmt.Sprintf("unable to parse upstream %s", addr)))
}
return u.Host
}