cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.1.3

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/config/config.go

235lines · modecode

1package config
2
3import (
4 "encoding/json"
5 "fmt"
6 "os"
7 "strings"
8 "time"
9
10 "github.com/cloudflare/pint/internal/checks"
11 "github.com/cloudflare/pint/internal/parser"
12
13 "github.com/hashicorp/hcl/v2/hclsimple"
14 "github.com/prometheus/common/model"
15 "github.com/rs/zerolog/log"
16)
17
18type Config struct {
19 CI *CI `hcl:"ci,block"`
20 Repository *Repository `hcl:"repository,block"`
21 Prometheus []PrometheusConfig `hcl:"prometheus,block"`
22 Checks *Checks `hcl:"checks,block"`
23 Rules []Rule `hcl:"rule,block"`
24}
25
26func (cfg *Config) SetDisabledChecks(l []string) {
27 disabled := map[string]struct{}{}
28 for _, s := range l {
29 re := strictRegex(s)
30 for _, name := range checks.CheckNames {
31 if re.MatchString(name) {
32 disabled[name] = struct{}{}
33 }
34 }
35 }
36 for name := range disabled {
37 var found bool
38 for _, c := range cfg.Checks.Disabled {
39 if c == name {
40 found = true
41 }
42 }
43 if !found {
44 cfg.Checks.Disabled = append(cfg.Checks.Disabled, name)
45 }
46 }
47}
48
49func (cfg Config) String() string {
50 content, _ := json.MarshalIndent(cfg, "", " ")
51 return string(content)
52}
53
54func (cfg Config) GetChecksForRule(path string, r parser.Rule) []checks.RuleChecker {
55 enabled := []checks.RuleChecker{}
56
57 if isEnabled(cfg.Checks.Enabled, cfg.Checks.Disabled, checks.SyntaxCheckName, r) {
58 enabled = append(enabled, checks.NewSyntaxCheck())
59 }
60
61 proms := []PrometheusConfig{}
62 for _, prom := range cfg.Prometheus {
63 if prom.isEnabledForPath(path) {
64 proms = append(proms, prom)
65 }
66 }
67 for _, rule := range cfg.Rules {
68 for _, c := range rule.resolveChecks(path, r, cfg.Checks.Enabled, cfg.Checks.Disabled, proms) {
69 if r.HasComment(fmt.Sprintf("disable %s", removeRedundantSpaces(c.String()))) {
70 log.Debug().
71 Str("path", path).
72 Str("check", c.String()).
73 Msg("Check disabled by comment")
74 continue
75 }
76 enabled = append(enabled, c)
77
78 }
79 }
80
81 el := []string{}
82 for _, e := range enabled {
83 el = append(el, fmt.Sprintf("%v", e))
84 }
85 name := "unknown"
86 if r.AlertingRule != nil {
87 name = r.AlertingRule.Alert.Value.Value
88 } else if r.RecordingRule != nil {
89 name = r.RecordingRule.Record.Value.Value
90 }
91 log.Debug().Strs("enabled", el).Str("path", path).Str("rule", name).Msg("Configured checks for rule")
92
93 return enabled
94}
95
96func Load(path string, failOnMissing bool) (cfg Config, err error) {
97 cfg = Config{
98 CI: &CI{
99 MaxCommits: 20,
100 BaseBranch: "master",
101 },
102 Checks: &Checks{
103 Enabled: checks.CheckNames,
104 Disabled: []string{},
105 },
106 Rules: []Rule{},
107 }
108
109 if _, err := os.Stat(path); err == nil || failOnMissing {
110 log.Info().Str("path", path).Msg("Loading configuration file")
111 err = hclsimple.DecodeFile(path, nil, &cfg)
112 if err != nil {
113 return cfg, err
114 }
115 }
116
117 if cfg.CI != nil {
118 if err = cfg.CI.validate(); err != nil {
119 return cfg, err
120 }
121 }
122
123 if cfg.Repository != nil && cfg.Repository.BitBucket != nil {
124 if err = cfg.Repository.BitBucket.validate(); err != nil {
125 return cfg, err
126 }
127 }
128
129 if cfg.Repository != nil && cfg.Repository.GitHub != nil {
130 if err = cfg.Repository.GitHub.validate(); err != nil {
131 return cfg, err
132 }
133 }
134
135 if cfg.Checks != nil {
136 if err = cfg.Checks.validate(); err != nil {
137 return cfg, err
138 }
139 }
140
141 for _, prom := range cfg.Prometheus {
142 if err = prom.validate(); err != nil {
143 return cfg, err
144 }
145 }
146
147 for _, rule := range cfg.Rules {
148 if rule.Match != nil {
149 if err = rule.Match.validate(); err != nil {
150 return cfg, err
151 }
152 }
153
154 for _, aggr := range rule.Aggregate {
155 if err = aggr.validate(); err != nil {
156 return cfg, err
157 }
158 }
159
160 if rule.Rate != nil {
161 if err = rule.Rate.validate(); err != nil {
162 return cfg, err
163 }
164 }
165
166 for _, ann := range rule.Annotation {
167 if err = ann.validate(); err != nil {
168 return cfg, err
169 }
170 }
171
172 for _, lab := range rule.Label {
173 if err = lab.validate(); err != nil {
174 return cfg, err
175 }
176 }
177
178 if rule.Cost != nil {
179 if err = rule.Cost.validate(); err != nil {
180 return cfg, err
181 }
182 }
183
184 if rule.Series != nil {
185 if err = rule.Series.validate(); err != nil {
186 return cfg, err
187 }
188 }
189
190 if rule.Alerts != nil {
191 if err = rule.Alerts.validate(); err != nil {
192 return cfg, err
193 }
194 }
195
196 for _, reject := range rule.Reject {
197 if err = reject.validate(); err != nil {
198 return cfg, err
199 }
200
201 }
202
203 if rule.Comparison != nil {
204 if err = rule.Comparison.validate(); err != nil {
205 return cfg, err
206 }
207 }
208
209 if rule.Template != nil {
210 if err = rule.Template.validate(); err != nil {
211 return cfg, err
212 }
213 }
214
215 if rule.VectorMatching != nil {
216 if err = rule.VectorMatching.validate(); err != nil {
217 return cfg, err
218 }
219 }
220 }
221
222 return cfg, nil
223}
224
225func parseDuration(d string) (time.Duration, error) {
226 mdur, err := model.ParseDuration(d)
227 if err != nil {
228 return 0, err
229 }
230 return time.Duration(mdur), nil
231}
232
233func removeRedundantSpaces(line string) string {
234 return strings.Join(strings.Fields(line), " ")
235}
236