/
config.go
150 lines (130 loc) · 4.21 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) The Thanos Authors.
// Licensed under the Apache License 2.0.
package alert
import (
"net"
"net/url"
"strconv"
"strings"
"time"
"github.com/pkg/errors"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/model/relabel"
"gopkg.in/yaml.v2"
"github.com/thanos-io/thanos/pkg/clientconfig"
"github.com/thanos-io/thanos/pkg/discovery/dns"
)
type AlertingConfig struct {
Alertmanagers []AlertmanagerConfig `yaml:"alertmanagers"`
}
// AlertmanagerConfig represents a client to a cluster of Alertmanager endpoints.
type AlertmanagerConfig struct {
HTTPClientConfig clientconfig.HTTPClientConfig `yaml:"http_config"`
EndpointsConfig clientconfig.HTTPEndpointsConfig `yaml:",inline"`
Timeout model.Duration `yaml:"timeout"`
APIVersion APIVersion `yaml:"api_version"`
}
// APIVersion represents the API version of the Alertmanager endpoint.
type APIVersion string
const (
APIv1 APIVersion = "v1"
APIv2 APIVersion = "v2"
)
var supportedAPIVersions = []APIVersion{
APIv1, APIv2,
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (v *APIVersion) UnmarshalYAML(unmarshal func(interface{}) error) error {
var s string
if err := unmarshal(&s); err != nil {
return errors.Wrap(err, "invalid Alertmanager API version")
}
for _, ver := range supportedAPIVersions {
if APIVersion(s) == ver {
*v = ver
return nil
}
}
return errors.Errorf("expected Alertmanager API version to be one of %v but got %q", supportedAPIVersions, s)
}
func DefaultAlertmanagerConfig() AlertmanagerConfig {
return AlertmanagerConfig{
EndpointsConfig: clientconfig.HTTPEndpointsConfig{
Scheme: "http",
StaticAddresses: []string{},
FileSDConfigs: []clientconfig.HTTPFileSDConfig{},
},
Timeout: model.Duration(time.Second * 10),
APIVersion: APIv1,
}
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *AlertmanagerConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
*c = DefaultAlertmanagerConfig()
type plain AlertmanagerConfig
return unmarshal((*plain)(c))
}
// LoadAlertingConfig loads a list of AlertmanagerConfig from YAML data.
func LoadAlertingConfig(confYaml []byte) (AlertingConfig, error) {
var cfg AlertingConfig
if err := yaml.UnmarshalStrict(confYaml, &cfg); err != nil {
return cfg, err
}
return cfg, nil
}
// BuildAlertmanagerConfig initializes and returns an Alertmanager client configuration from a static address.
func BuildAlertmanagerConfig(address string, timeout time.Duration) (AlertmanagerConfig, error) {
parsed, err := url.Parse(address)
if err != nil {
return AlertmanagerConfig{}, err
}
scheme := parsed.Scheme
if scheme == "" {
return AlertmanagerConfig{}, errors.New("alertmanagers.url contains empty scheme")
}
host := parsed.Host
if host == "" {
return AlertmanagerConfig{}, errors.New("alertmanagers.url contains empty host")
}
for _, qType := range []dns.QType{dns.A, dns.SRV, dns.SRVNoA} {
prefix := string(qType) + "+"
if strings.HasPrefix(strings.ToLower(scheme), prefix) {
// Scheme is of the form "<dns type>+<http scheme>".
scheme = strings.TrimPrefix(scheme, prefix)
host = prefix + parsed.Host
if qType == dns.A {
if _, _, err := net.SplitHostPort(parsed.Host); err != nil {
// The host port could be missing. Append the defaultAlertmanagerPort.
host = host + ":" + strconv.Itoa(defaultAlertmanagerPort)
}
}
break
}
}
var basicAuth clientconfig.BasicAuth
if parsed.User != nil && parsed.User.String() != "" {
basicAuth.Username = parsed.User.Username()
pw, _ := parsed.User.Password()
basicAuth.Password = pw
}
return AlertmanagerConfig{
HTTPClientConfig: clientconfig.HTTPClientConfig{
BasicAuth: basicAuth,
},
EndpointsConfig: clientconfig.HTTPEndpointsConfig{
PathPrefix: parsed.Path,
Scheme: scheme,
StaticAddresses: []string{host},
},
Timeout: model.Duration(timeout),
APIVersion: APIv1,
}, nil
}
// LoadRelabelConfigs loads a list of relabel.Config from YAML data.
func LoadRelabelConfigs(confYaml []byte) ([]*relabel.Config, error) {
var cfg []*relabel.Config
if err := yaml.UnmarshalStrict(confYaml, &cfg); err != nil {
return nil, err
}
return cfg, nil
}