-
Notifications
You must be signed in to change notification settings - Fork 3
/
config.go
135 lines (118 loc) · 3.82 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
130
131
132
133
134
135
package waitfor
import (
"errors"
"io"
"strings"
"time"
yaml "gopkg.in/yaml.v3"
)
// DefaultTimeout is the amount of time to wait for target before failing
const DefaultTimeout = time.Second * 5
// DefaultHTTPClientTimeout a default value for a time limit for requests made by http client
const DefaultHTTPClientTimeout = time.Second
// DefaultStatusPattern is a default value for the Regex pattern to match in the expected result
const DefaultStatusPattern = "^2..$"
// TargetConfig is the configuration of a single target
type TargetConfig struct {
// Type is the kind of target being described
Type string
// Target is the location of the target to be tested
Target string
// Timeout is the timeout to use for this specific target if it is different to DefaultTimeout
Timeout time.Duration
// HTTPClientTimeout is the timeout for requests made by a http client
HTTPClientTimeout time.Duration `yaml:"http-client-timeout"`
// Regex is the regular expression pattern to match in the expected http status code result
StatusPattern string `yaml:"http-client-status-pattern"`
}
// Config represents all the config that can be defined in a config file
type Config struct {
DefaultTimeout time.Duration `yaml:"default-timeout"`
Targets map[string]TargetConfig
DefaultHTTPClientTimeout time.Duration `yaml:"default-http-client-timeout"`
DefaultStatusPattern string `yaml:"default-http-client-status-pattern"`
}
// NewConfig creates an empty Config
func NewConfig() *Config {
return &Config{
DefaultTimeout: DefaultTimeout,
Targets: map[string]TargetConfig{},
DefaultHTTPClientTimeout: DefaultHTTPClientTimeout,
DefaultStatusPattern: DefaultStatusPattern,
}
}
// NewConfigFromFile reads configuration from the file provided
func NewConfigFromFile(r io.Reader) (*Config, error) {
config := Config{}
err := yaml.NewDecoder(r).Decode(&config)
if err != nil {
return nil, err
}
if config.DefaultTimeout == 0 {
config.DefaultTimeout = DefaultTimeout
}
if config.DefaultHTTPClientTimeout == 0 {
config.DefaultHTTPClientTimeout = DefaultHTTPClientTimeout
}
if config.DefaultStatusPattern == "" {
config.DefaultStatusPattern = DefaultStatusPattern
}
for t := range config.Targets {
target := config.Targets[t]
if config.Targets[t].Timeout == 0 {
target.Timeout = config.DefaultTimeout
}
if config.Targets[t].HTTPClientTimeout == 0 {
target.HTTPClientTimeout = config.DefaultHTTPClientTimeout
}
if config.Targets[t].StatusPattern == "" {
target.StatusPattern = config.DefaultStatusPattern
}
config.Targets[t] = target
}
return &config, nil
}
// GotTarget returns true if the target exists in this config
func (c *Config) GotTarget(t string) bool {
_, ok := c.Targets[t]
return ok
}
// AddFromString adds a new target from a string using the format <type>:<target location>
func (c *Config) AddFromString(t string) error {
if strings.HasPrefix(t, "tcp:") {
c.Targets[t] = TargetConfig{
Target: strings.Replace(t, "tcp:", "", 1),
Type: "tcp",
Timeout: c.DefaultTimeout,
}
return nil
}
if strings.HasPrefix(t, "http:") || strings.HasPrefix(t, "https:") {
c.Targets[t] = TargetConfig{
Target: t,
Type: "http",
Timeout: c.DefaultTimeout,
HTTPClientTimeout: c.DefaultHTTPClientTimeout,
StatusPattern: c.DefaultStatusPattern,
}
return nil
}
if strings.HasPrefix(t, "dns:") {
c.Targets[t] = TargetConfig{
Target: strings.Replace(t, "dns:", "", 1),
Type: "dns",
Timeout: c.DefaultTimeout,
}
return nil
}
return errors.New("unable to understand target " + t)
}
func (c *Config) Filter(targets []string) *Config {
result := NewConfig()
for _, target := range targets {
if c.GotTarget(target) {
result.Targets[target] = c.Targets[target]
}
}
return result
}