From 88c3052ce3811c64ce5f76554c8f0ab647b1b0b3 Mon Sep 17 00:00:00 2001 From: Lukasz Mierzwa Date: Tue, 31 Oct 2023 10:17:23 +0000 Subject: [PATCH] Added alerts/external_labels check --- cmd/pint/tests/0023_enabled_checks.txt | 8 +- cmd/pint/tests/0025_config.txt | 1 + cmd/pint/tests/0037_disable_checks.txt | 3 + .../tests/0054_watch_metrics_prometheus.txt | 4 + .../0057_watch_metrics_prometheus_ignore.txt | 2 + cmd/pint/tests/0103_file_disable.txt | 2 +- cmd/pint/tests/0113_config_env_expand.txt | 1 + cmd/pint/tests/0115_file_disable_tag.txt | 2 +- docs/changelog.md | 6 + docs/checks/alerts/external_labels.md | 118 ++ internal/checks/alerts_external_labels.go | 132 +++ .../checks/alerts_external_labels_test.go | 157 +++ internal/checks/base.go | 2 + .../config/__snapshots__/config_test.snap | 1034 ++++++++++------- internal/config/config.go | 5 + internal/config/config_test.go | 25 +- 16 files changed, 1043 insertions(+), 459 deletions(-) create mode 100644 docs/checks/alerts/external_labels.md create mode 100644 internal/checks/alerts_external_labels.go create mode 100644 internal/checks/alerts_external_labels_test.go diff --git a/cmd/pint/tests/0023_enabled_checks.txt b/cmd/pint/tests/0023_enabled_checks.txt index 5d18212a..a1ad90af 100644 --- a/cmd/pint/tests/0023_enabled_checks.txt +++ b/cmd/pint/tests/0023_enabled_checks.txt @@ -1,9 +1,9 @@ pint.error -l debug --no-color lint rules ! stdout . -stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)"] path=rules/1.yaml rule=one' -stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)"] path=rules/1.yaml rule=two' -stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)"] path=rules/2.yaml rule=one' -stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)"] path=rules/2.yaml rule=two' +stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)","alerts/external_labels\(prom\)"] path=rules/1.yaml rule=one' +stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)","alerts/external_labels\(prom\)"] path=rules/1.yaml rule=two' +stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)","alerts/external_labels\(prom\)"] path=rules/2.yaml rule=one' +stderr 'level=DEBUG msg="Configured checks for rule" enabled=\["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/rate\(prom\)","promql/series\(prom\)","promql/vector_matching\(prom\)"\,"promql/range_query\(prom\)","rule/duplicate\(prom\)","labels/conflict\(prom\)","alerts/external_labels\(prom\)"] path=rules/2.yaml rule=two' -- rules/1.yaml -- - record: one diff --git a/cmd/pint/tests/0025_config.txt b/cmd/pint/tests/0025_config.txt index 11bec78b..8cb2fd34 100644 --- a/cmd/pint/tests/0025_config.txt +++ b/cmd/pint/tests/0025_config.txt @@ -98,6 +98,7 @@ level=INFO msg="Loading configuration file" path=.pint.hcl "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", diff --git a/cmd/pint/tests/0037_disable_checks.txt b/cmd/pint/tests/0037_disable_checks.txt index ca93f195..b1f81cc0 100644 --- a/cmd/pint/tests/0037_disable_checks.txt +++ b/cmd/pint/tests/0037_disable_checks.txt @@ -39,6 +39,9 @@ prometheus "prom" { uri = "http://127.0.0.1" timeout = "5s" } +checks { + disabled = [ "alerts/external_labels" ] +} rule { match { kind = "recording" diff --git a/cmd/pint/tests/0054_watch_metrics_prometheus.txt b/cmd/pint/tests/0054_watch_metrics_prometheus.txt index 5562e24c..cc33e83a 100644 --- a/cmd/pint/tests/0054_watch_metrics_prometheus.txt +++ b/cmd/pint/tests/0054_watch_metrics_prometheus.txt @@ -44,6 +44,8 @@ parser { # TYPE pint_check_duration_seconds summary pint_check_duration_seconds_sum{check="alerts/comparison"} pint_check_duration_seconds_count{check="alerts/comparison"} +pint_check_duration_seconds_sum{check="alerts/external_labels"} +pint_check_duration_seconds_count{check="alerts/external_labels"} pint_check_duration_seconds_sum{check="alerts/for"} pint_check_duration_seconds_count{check="alerts/for"} pint_check_duration_seconds_sum{check="alerts/template"} @@ -89,6 +91,8 @@ pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",p pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="couldn't run \"promql/series\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/series",severity="bug"} pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="prometheus \"prom1\" at http://127.0.0.1:7054 failed with: bad_data: bogus query",reporter="promql/series",severity="bug"} pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"alerts/external_labels\" checks due to prometheus \"prom1\" at http://127.0.0.1:7054 connection error: server_error: server error: 500",reporter="alerts/external_labels",severity="bug"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"alerts/external_labels\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="alerts/external_labels",severity="bug"} pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"promql/range_query\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/range_query",severity="bug"} pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"promql/rate\" checks due to prometheus \"prom1\" at http://127.0.0.1:7054 connection error: server_error: server error: 500",reporter="promql/rate",severity="bug"} pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"promql/rate\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/rate",severity="bug"} diff --git a/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt b/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt index 77469293..22bdb392 100644 --- a/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt +++ b/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt @@ -42,6 +42,8 @@ parser { # TYPE pint_check_duration_seconds summary pint_check_duration_seconds_sum{check="alerts/comparison"} pint_check_duration_seconds_count{check="alerts/comparison"} +pint_check_duration_seconds_sum{check="alerts/external_labels"} +pint_check_duration_seconds_count{check="alerts/external_labels"} pint_check_duration_seconds_sum{check="alerts/for"} pint_check_duration_seconds_count{check="alerts/for"} pint_check_duration_seconds_sum{check="alerts/template"} diff --git a/cmd/pint/tests/0103_file_disable.txt b/cmd/pint/tests/0103_file_disable.txt index 9fa2acde..3f039248 100644 --- a/cmd/pint/tests/0103_file_disable.txt +++ b/cmd/pint/tests/0103_file_disable.txt @@ -10,7 +10,7 @@ level=INFO msg="Configured new Prometheus server" name=prom uris=1 tags=[] inclu level=DEBUG msg="Generated all Prometheus servers" count=1 level=DEBUG msg="Found recording rule" path=rules/0001.yml record=colo:test1 lines=9-10 level=DEBUG msg="Starting query workers" name=prom uri=http://127.0.0.1:7103 workers=16 -level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/vector_matching(prom)","labels/conflict(prom)"] path=rules/0001.yml rule=colo:test1 +level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/vector_matching(prom)","labels/conflict(prom)","alerts/external_labels(prom)"] path=rules/0001.yml rule=colo:test1 level=DEBUG msg="Stopping query workers" name=prom uri=http://127.0.0.1:7103 -- rules/0001.yml -- # This should skip all online checks diff --git a/cmd/pint/tests/0113_config_env_expand.txt b/cmd/pint/tests/0113_config_env_expand.txt index ef5960f5..d7193405 100644 --- a/cmd/pint/tests/0113_config_env_expand.txt +++ b/cmd/pint/tests/0113_config_env_expand.txt @@ -35,6 +35,7 @@ level=INFO msg="Loading configuration file" path=.pint.hcl "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", diff --git a/cmd/pint/tests/0115_file_disable_tag.txt b/cmd/pint/tests/0115_file_disable_tag.txt index 227325dd..2d5c9ebe 100644 --- a/cmd/pint/tests/0115_file_disable_tag.txt +++ b/cmd/pint/tests/0115_file_disable_tag.txt @@ -10,7 +10,7 @@ level=INFO msg="Configured new Prometheus server" name=prom uris=1 tags=["foo"," level=DEBUG msg="Generated all Prometheus servers" count=1 level=DEBUG msg="Found recording rule" path=rules/0001.yml record=colo:test1 lines="6 8" level=DEBUG msg="Starting query workers" name=prom uri=http://127.0.0.1:7103 workers=16 -level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp"] path=rules/0001.yml rule=colo:test1 +level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","alerts/external_labels(prom)"] path=rules/0001.yml rule=colo:test1 level=DEBUG msg="Stopping query workers" name=prom uri=http://127.0.0.1:7103 -- rules/0001.yml -- # pint file/disable promql/series(+bar) diff --git a/docs/changelog.md b/docs/changelog.md index d3b9eca8..ebcd2977 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,11 @@ # Changelog +## v0.49.0 + +### Added + +- Added [alerts/external_labels](checks/alerts/external_labels.md) check. + ## v0.48.2 ### Fixed diff --git a/docs/checks/alerts/external_labels.md b/docs/checks/alerts/external_labels.md new file mode 100644 index 00000000..71495f8b --- /dev/null +++ b/docs/checks/alerts/external_labels.md @@ -0,0 +1,118 @@ +--- +layout: default +parent: Checks +grand_parent: Documentation +--- + +# alerts/external_labels + +Alerting rules can be templated to render the value of external labels +configured for the Prometheus server these rules are being evaluated +using `$externalLabels` variable. +[See docs](https://prometheus.io/docs/prometheus/latest/configuration/template_reference/#alert-field-templates). + +This check will look for alerting rules referencing external labels that are +not present on given Prometheus server. + +If we define `cluster` label in `global:external_labels`, example: + +```yaml +global: + external_labels: + cluster: mycluster +``` + +Then we can access it in alert rules deployed to that Prometheus server +by using `$externalLabels.cluster` variable: + +```yaml +- alert: Abc Is Down + expr: up{job="abc"} == 0 + annotations: + summary: "{{ $labels.job }} is down in {{ $externalLabels.cluster }} cluster" +``` + +But if we try to do that without `cluster` in `global:external_labels` configuration +then `$externalLabels.cluster` will be empty, and this is what this check would +report. + +## Configuration + +This check doesn't have any configuration options. + +## How to enable it + +This check is enabled by default for all configured Prometheus servers. + +Example: + +```js +prometheus "prod" { + uri = "https://prometheus-prod.example.com" + timeout = "60s" + include = [ + "rules/prod/.*", + "rules/common/.*", + ] +} + +prometheus "dev" { + uri = "https://prometheus-dev.example.com" + timeout = "30s" + include = [ + "rules/dev/.*", + "rules/common/.*", + ] +} +``` + +## How to disable it + +You can disable this check globally by adding this config block: + +```js +checks { + disabled = ["alerts/external_labels"] +} +``` + +You can also disable it for all rules inside given file by adding +a comment anywhere in that file. Example: + +```yaml +# pint file/disable alerts/external_labels +``` + +Or you can disable it per rule by adding a comment to it. Example: + +```yaml +# pint disable alerts/external_labels +``` + +If you want to disable only individual instances of this check +you can add a more specific comment. + +```yaml +# pint disable alerts/external_labels($prometheus) +``` + +Where `$prometheus` is the name of Prometheus server to disable. + +Example: + +```yaml +# pint disable alerts/external_labels(prod) +``` + +## How to snooze it + +You can disable this check until given time by adding a comment to it. Example: + +```yaml +# pint snooze $TIMESTAMP alerts/external_labels +``` + +Where `$TIMESTAMP` is either use [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) +formatted or `YYYY-MM-DD`. +Adding this comment will disable `alerts/external_labels` _until_ `$TIMESTAMP`, after that +check will be re-enabled. diff --git a/internal/checks/alerts_external_labels.go b/internal/checks/alerts_external_labels.go new file mode 100644 index 00000000..de71e528 --- /dev/null +++ b/internal/checks/alerts_external_labels.go @@ -0,0 +1,132 @@ +package checks + +import ( + "context" + "fmt" + + "github.com/cloudflare/pint/internal/discovery" + "github.com/cloudflare/pint/internal/parser" + "github.com/cloudflare/pint/internal/promapi" +) + +const ( + AlertsExternalLabelsCheckName = "alerts/external_labels" +) + +func NewAlertsExternalLabelsCheck(prom *promapi.FailoverGroup) AlertsExternalLabelsCheck { + return AlertsExternalLabelsCheck{ + prom: prom, + } +} + +type AlertsExternalLabelsCheck struct { + prom *promapi.FailoverGroup +} + +func (c AlertsExternalLabelsCheck) Meta() CheckMeta { + return CheckMeta{IsOnline: true} +} + +func (c AlertsExternalLabelsCheck) String() string { + return fmt.Sprintf("%s(%s)", AlertsExternalLabelsCheckName, c.prom.Name()) +} + +func (c AlertsExternalLabelsCheck) Reporter() string { + return AlertsExternalLabelsCheckName +} + +func (c AlertsExternalLabelsCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ []discovery.Entry) (problems []Problem) { + if rule.AlertingRule == nil { + return problems + } + + if rule.AlertingRule.Expr.SyntaxError != nil { + return problems + } + + cfg, err := c.prom.Config(ctx) + if err != nil { + text, severity := textAndSeverityFromError(err, c.Reporter(), c.prom.Name(), Bug) + problems = append(problems, Problem{ + Fragment: fmt.Sprintf("%s: %s", rule.AlertingRule.Alert.Key.Value, rule.AlertingRule.Alert.Value.Value), + Lines: rule.AlertingRule.Lines(), + Reporter: c.Reporter(), + Text: text, + Severity: severity, + }) + return problems + } + + if rule.AlertingRule.Labels != nil { + for _, label := range rule.AlertingRule.Labels.Items { + for _, name := range checkExternalLabels(label.Key.Value, label.Key.Value, cfg.Config.Global.ExternalLabels) { + problems = append(problems, Problem{ + Fragment: fmt.Sprintf("%s: %s", label.Key.Value, label.Value.Value), + Lines: label.Lines(), + Reporter: c.Reporter(), + Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), + Severity: Bug, + }) + } + for _, name := range checkExternalLabels(label.Key.Value, label.Value.Value, cfg.Config.Global.ExternalLabels) { + problems = append(problems, Problem{ + Fragment: fmt.Sprintf("%s: %s", label.Key.Value, label.Value.Value), + Lines: label.Lines(), + Reporter: c.Reporter(), + Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), Severity: Bug, + }) + } + } + } + + if rule.AlertingRule.Annotations != nil { + for _, annotation := range rule.AlertingRule.Annotations.Items { + for _, name := range checkExternalLabels(annotation.Key.Value, annotation.Key.Value, cfg.Config.Global.ExternalLabels) { + problems = append(problems, Problem{ + Fragment: fmt.Sprintf("%s: %s", annotation.Key.Value, annotation.Value.Value), + Lines: annotation.Lines(), + Reporter: c.Reporter(), + Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), + Severity: Bug, + }) + } + for _, name := range checkExternalLabels(annotation.Key.Value, annotation.Value.Value, cfg.Config.Global.ExternalLabels) { + problems = append(problems, Problem{ + Fragment: fmt.Sprintf("%s: %s", annotation.Key.Value, annotation.Value.Value), + Lines: annotation.Lines(), + Reporter: c.Reporter(), + Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), + Severity: Bug, + }) + } + } + } + + return problems +} + +func checkExternalLabels(name, text string, externalLabels map[string]string) (labels []string) { + vars, aliases, ok := findTemplateVariables(name, text) + if !ok { + return nil + } + + done := map[string]struct{}{} + externalLabelsAliases := aliases.varAliases(".ExternalLabels") + for _, v := range vars { + for _, a := range externalLabelsAliases { + if len(v) > 1 && v[0] == a { + name := v[1] + if _, ok = done[name]; ok { + continue + } + if _, ok := externalLabels[name]; !ok { + labels = append(labels, name) + } + done[name] = struct{}{} + } + } + } + + return labels +} diff --git a/internal/checks/alerts_external_labels_test.go b/internal/checks/alerts_external_labels_test.go new file mode 100644 index 00000000..c27298c2 --- /dev/null +++ b/internal/checks/alerts_external_labels_test.go @@ -0,0 +1,157 @@ +package checks_test + +import ( + "fmt" + "testing" + "time" + + "github.com/cloudflare/pint/internal/checks" + "github.com/cloudflare/pint/internal/promapi" +) + +func newAlertsExternalLabelsCheck(prom *promapi.FailoverGroup) checks.RuleChecker { + return checks.NewAlertsExternalLabelsCheck(prom) +} + +func alertsExternalLabelsText(name, uri, label string) string { + return fmt.Sprintf("template is using %q external label but prometheus %q at %s doesn't have this label configured in global:external_labels", label, name, uri) +} + +func TestAlertsExternalLabelsCountCheck(t *testing.T) { + content := ` +- alert: Foo Is Down + expr: up{job="foo"} == 0 + annotations: + summary: "{{ $labels.job }} is down" + "{{.ExternalLabels.cluster}}": "This is {{ .ExternalLabels.cluster }} cluster" + labels: + job: "{{ $labels.job }}" + cluster: "{{ $externalLabels.cluster }} / {{ $externalLabels.cluster }}" + "{{ $externalLabels.cluster }}": "{{ $externalLabels.cluster }}" +` + + testCases := []checkTest{ + { + description: "ignores recording rules", + content: "- record: foo\n expr: up == 0\n", + checker: newAlertsExternalLabelsCheck, + prometheus: newSimpleProm, + problems: noProblems, + }, + { + description: "ignores rules with syntax errors", + content: "- alert: Foo Is Down\n expr: sum(\n", + checker: newAlertsExternalLabelsCheck, + prometheus: newSimpleProm, + problems: noProblems, + }, + { + description: "bad request", + content: content, + checker: newAlertsExternalLabelsCheck, + prometheus: newSimpleProm, + problems: func(uri string) []checks.Problem { + return []checks.Problem{ + { + Fragment: "alert: Foo Is Down", + Lines: []int{2, 3, 4, 5, 6, 7, 8, 9, 10}, + Reporter: checks.AlertsExternalLabelsCheckName, + Text: checkErrorBadData("prom", uri, "bad_data: bad input data"), + Severity: checks.Bug, + }, + } + }, + mocks: []*prometheusMock{ + { + conds: []requestCondition{requireConfigPath}, + resp: respondWithBadData(), + }, + }, + }, + { + description: "connection refused / upstream not required / warning", + content: content, + checker: newAlertsExternalLabelsCheck, + prometheus: func(s string) *promapi.FailoverGroup { + return simpleProm("prom", "http://127.0.0.1:1111", time.Second*5, false) + }, + problems: func(uri string) []checks.Problem { + return []checks.Problem{ + { + Fragment: "alert: Foo Is Down", + Lines: []int{2, 3, 4, 5, 6, 7, 8, 9, 10}, + Reporter: checks.AlertsExternalLabelsCheckName, + Text: checkErrorUnableToRun(checks.AlertsExternalLabelsCheckName, "prom", "http://127.0.0.1:1111", `connection refused`), + Severity: checks.Warning, + }, + } + }, + }, + { + description: "all labels present", + content: content, + checker: newAlertsExternalLabelsCheck, + prometheus: newSimpleProm, + problems: noProblems, + mocks: []*prometheusMock{ + { + conds: []requestCondition{requireConfigPath}, + resp: configResponse{yaml: "global:\n external_labels:\n cluster: foo\n"}, + }, + }, + }, + { + description: "no cluster label", + content: content, + checker: newAlertsExternalLabelsCheck, + prometheus: newSimpleProm, + problems: func(uri string) []checks.Problem { + return []checks.Problem{ + { + Fragment: `cluster: {{ $externalLabels.cluster }} / {{ $externalLabels.cluster }}`, + Lines: []int{9}, + Reporter: checks.AlertsExternalLabelsCheckName, + Text: alertsExternalLabelsText("prom", uri, "cluster"), + Severity: checks.Bug, + }, + { + Fragment: `{{ $externalLabels.cluster }}: {{ $externalLabels.cluster }}`, + Lines: []int{10}, + Reporter: checks.AlertsExternalLabelsCheckName, + Text: alertsExternalLabelsText("prom", uri, "cluster"), + Severity: checks.Bug, + }, + { + Fragment: `{{ $externalLabels.cluster }}: {{ $externalLabels.cluster }}`, + Lines: []int{10}, + Reporter: checks.AlertsExternalLabelsCheckName, + Text: alertsExternalLabelsText("prom", uri, "cluster"), + Severity: checks.Bug, + }, + { + Fragment: `{{.ExternalLabels.cluster}}: This is {{ .ExternalLabels.cluster }} cluster`, + Lines: []int{6}, + Reporter: checks.AlertsExternalLabelsCheckName, + Text: alertsExternalLabelsText("prom", uri, "cluster"), + Severity: checks.Bug, + }, + { + Fragment: `{{.ExternalLabels.cluster}}: This is {{ .ExternalLabels.cluster }} cluster`, + Lines: []int{6}, + Reporter: checks.AlertsExternalLabelsCheckName, + Text: alertsExternalLabelsText("prom", uri, "cluster"), + Severity: checks.Bug, + }, + } + }, + mocks: []*prometheusMock{ + { + conds: []requestCondition{requireConfigPath}, + resp: configResponse{yaml: "global:\n external_labels:\n bob: foo\n"}, + }, + }, + }, + } + + runTests(t, testCases) +} diff --git a/internal/checks/base.go b/internal/checks/base.go index 4d7c183e..1c8881c0 100644 --- a/internal/checks/base.go +++ b/internal/checks/base.go @@ -14,6 +14,7 @@ var ( CheckNames = []string{ AnnotationCheckName, AlertsCheckName, + AlertsExternalLabelsCheckName, AlertForCheckName, TemplateCheckName, LabelsConflictCheckName, @@ -35,6 +36,7 @@ var ( } OnlineChecks = []string{ AlertsCheckName, + AlertsExternalLabelsCheckName, LabelsConflictCheckName, RangeQueryCheckName, RateCheckName, diff --git a/internal/config/__snapshots__/config_test.snap b/internal/config/__snapshots__/config_test.snap index 8e55464b..391e7445 100755 --- a/internal/config/__snapshots__/config_test.snap +++ b/internal/config/__snapshots__/config_test.snap @@ -1,40 +1,45 @@ -[TestGetChecksForRule/defaults - 1] +[TestGetChecksForRule/two_checks_enabled_via_config - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, + "prometheus": [ + { + "name": "prom1", + "uri": "http://localhost", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "include": [ + "rules.yml" + ], + "required": false + } + ], "checks": { "enabled": [ - "alerts/annotation", - "alerts/count", - "alerts/for", - "alerts/template", - "labels/conflict", - "promql/aggregate", - "alerts/comparison", - "promql/fragile", - "promql/range_query", - "promql/rate", - "promql/regexp", "promql/syntax", - "promql/vector_matching", - "query/cost", - "promql/series", - "rule/duplicate", - "rule/for", - "rule/label", - "rule/link", - "rule/reject" + "alerts/count" ] }, + "rules": [ + { + "alerts": { + "range": "1h", + "step": "1m", + "resolve": "5m" + } + } + ], "owners": {} } --- -[TestGetChecksForRule/single_prometheus_server - 1] +[TestGetChecksForRule/rule_with_ignore_block_/_mismatch - 1] { "ci": { "maxCommits": 20, @@ -43,19 +48,99 @@ "parser": {}, "prometheus": [ { - "name": "prom", + "name": "prom1", + "uri": "http://localhost", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "include": [ + "rules.yml" + ], + "required": false + } + ], + "checks": { + "enabled": [ + "promql/syntax", + "alerts/count" + ] + }, + "rules": [ + { + "ignore": [ + { + "path": "foo.xml" + } + ], + "alerts": { + "range": "1h", + "step": "1m", + "resolve": "5m" + } + } + ], + "owners": {} +} +--- + +[TestGetChecksForRule/rule_with_ignore_block_/_match - 1] +{ + "ci": { + "maxCommits": 20, + "baseBranch": "master" + }, + "parser": {}, + "prometheus": [ + { + "name": "prom1", "uri": "http://localhost", "timeout": "1s", "concurrency": 16, "rateLimit": 100, "uptime": "up", + "include": [ + "rules.yml" + ], "required": false } ], + "checks": { + "enabled": [ + "promql/syntax", + "alerts/count" + ] + }, + "rules": [ + { + "ignore": [ + { + "path": "rules.yml" + } + ], + "alerts": { + "range": "1h", + "step": "1m", + "resolve": "5m" + } + } + ], + "owners": {} +} +--- + +[TestGetChecksForRule/defaults - 1] +{ + "ci": { + "maxCommits": 20, + "baseBranch": "master" + }, + "parser": {}, "checks": { "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -80,7 +165,7 @@ } --- -[TestGetChecksForRule/multiple_URIs - 1] +[TestGetChecksForRule/single_prometheus_server - 1] { "ci": { "maxCommits": 20, @@ -91,10 +176,6 @@ { "name": "prom", "uri": "http://localhost", - "failover": [ - "http://localhost/1", - "http://localhost/2" - ], "timeout": "1s", "concurrency": 16, "rateLimit": 100, @@ -106,6 +187,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -130,7 +212,7 @@ } --- -[TestGetChecksForRule/two_prometheus_servers_/_disable_all_checks_via_comment - 1] +[TestGetChecksForRule/multiple_URIs - 1] { "ci": { "maxCommits": 20, @@ -139,17 +221,12 @@ "parser": {}, "prometheus": [ { - "name": "prom1", - "uri": "http://localhost/1", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "required": false - }, - { - "name": "prom2", - "uri": "http://localhost/2", + "name": "prom", + "uri": "http://localhost", + "failover": [ + "http://localhost/1", + "http://localhost/2" + ], "timeout": "1s", "concurrency": 16, "rateLimit": 100, @@ -161,6 +238,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -179,9 +257,6 @@ "rule/label", "rule/link", "rule/reject" - ], - "disabled": [ - "alerts/template" ] }, "owners": {} @@ -213,6 +288,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -265,6 +341,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -314,6 +391,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -363,6 +441,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -424,6 +503,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -459,6 +539,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -497,6 +578,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -553,6 +635,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -609,6 +692,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -641,72 +725,6 @@ } --- -[TestGetChecksForRule/prometheus_check_with_prometheus_servers_and_disable_comment - 1] -{ - "ci": { - "maxCommits": 20, - "baseBranch": "master" - }, - "parser": {}, - "prometheus": [ - { - "name": "prom1", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - }, - { - "name": "prom2", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - } - ], - "checks": { - "enabled": [ - "alerts/annotation", - "alerts/count", - "alerts/for", - "alerts/template", - "labels/conflict", - "promql/aggregate", - "alerts/comparison", - "promql/fragile", - "promql/range_query", - "promql/rate", - "promql/regexp", - "promql/syntax", - "promql/vector_matching", - "query/cost", - "promql/series", - "rule/duplicate", - "rule/for", - "rule/label", - "rule/link", - "rule/reject" - ] - }, - "rules": [ - { - "cost": {} - } - ], - "owners": {} -} ---- - [TestGetChecksForRule/duplicated_rules - 1] { "ci": { @@ -718,6 +736,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -787,87 +806,7 @@ } --- -[TestGetChecksForRule/multiple_cost_checks - 1] -{ - "ci": { - "maxCommits": 20, - "baseBranch": "master" - }, - "parser": {}, - "prometheus": [ - { - "name": "prom1", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - }, - { - "name": "prom2", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - } - ], - "checks": { - "enabled": [ - "alerts/annotation", - "alerts/count", - "alerts/for", - "alerts/template", - "labels/conflict", - "promql/aggregate", - "alerts/comparison", - "promql/fragile", - "promql/range_query", - "promql/rate", - "promql/regexp", - "promql/syntax", - "promql/vector_matching", - "query/cost", - "promql/series", - "rule/duplicate", - "rule/for", - "rule/label", - "rule/link", - "rule/reject" - ] - }, - "rules": [ - { - "cost": { - "severity": "info" - } - }, - { - "cost": { - "maxSeries": 10000, - "severity": "warning" - } - }, - { - "cost": { - "maxSeries": 20000, - "severity": "bug" - } - } - ], - "owners": {} -} ---- - -[TestGetChecksForRule/reject_rules - 1] +[TestGetChecksForRule/reject_rules - 1] { "ci": { "maxCommits": 20, @@ -878,6 +817,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -933,6 +873,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -989,6 +930,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1045,6 +987,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1101,6 +1044,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1157,6 +1101,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1213,6 +1158,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1269,6 +1215,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1314,31 +1261,18 @@ } --- -[TestGetChecksForRule/checks_disabled_via_config - 1] +[TestGetChecksForRule/for_match_/_passing - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, - "prometheus": [ - { - "name": "prom1", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - } - ], "checks": { "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1357,194 +1291,181 @@ "rule/label", "rule/link", "rule/reject" - ], - "disabled": [ - "promql/rate", - "promql/vector_matching", - "promql/range_query", - "rule/duplicate", - "labels/conflict" ] }, "rules": [ { - "alerts": { - "range": "1h", - "step": "1m", - "resolve": "5m" - } - } - ], - "owners": {} -} ---- - -[TestGetChecksForRule/single_check_enabled_via_config - 1] -{ - "ci": { - "maxCommits": 20, - "baseBranch": "master" - }, - "parser": {}, - "prometheus": [ - { - "name": "prom1", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" + "match": [ + { + "for": "\u003e 15m" + } ], - "required": false - } - ], - "checks": {}, - "rules": [ - { - "alerts": { - "range": "1h", - "step": "1m", - "resolve": "5m" - } + "annotation": [ + { + "key": "summary", + "required": true + } + ] } ], "owners": {} } --- -[TestGetChecksForRule/two_checks_enabled_via_config - 1] +[TestGetChecksForRule/for_match_/_not_passing - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, - "prometheus": [ - { - "name": "prom1", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - } - ], "checks": { "enabled": [ + "alerts/annotation", + "alerts/count", + "alerts/external_labels", + "alerts/for", + "alerts/template", + "labels/conflict", + "promql/aggregate", + "alerts/comparison", + "promql/fragile", + "promql/range_query", + "promql/rate", + "promql/regexp", "promql/syntax", - "alerts/count" + "promql/vector_matching", + "query/cost", + "promql/series", + "rule/duplicate", + "rule/for", + "rule/label", + "rule/link", + "rule/reject" ] }, "rules": [ { - "alerts": { - "range": "1h", - "step": "1m", - "resolve": "5m" - } + "match": [ + { + "for": "\u003e 15m" + } + ], + "annotation": [ + { + "key": "summary", + "required": true + } + ] } ], "owners": {} } --- -[TestGetChecksForRule/rule_with_ignore_block_/_mismatch - 1] +[TestGetChecksForRule/for_match_/_passing#01 - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, - "prometheus": [ - { - "name": "prom1", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - } - ], "checks": { "enabled": [ + "alerts/annotation", + "alerts/count", + "alerts/external_labels", + "alerts/for", + "alerts/template", + "labels/conflict", + "promql/aggregate", + "alerts/comparison", + "promql/fragile", + "promql/range_query", + "promql/rate", + "promql/regexp", "promql/syntax", - "alerts/count" + "promql/vector_matching", + "query/cost", + "promql/series", + "rule/duplicate", + "rule/for", + "rule/label", + "rule/link", + "rule/reject" ] }, "rules": [ { - "ignore": [ + "match": [ { - "path": "foo.xml" + "keep_firing_for": "\u003e 15m" } ], - "alerts": { - "range": "1h", - "step": "1m", - "resolve": "5m" - } + "annotation": [ + { + "key": "summary", + "required": true + } + ] } ], "owners": {} } --- -[TestGetChecksForRule/rule_with_ignore_block_/_match - 1] +[TestGetChecksForRule/for_match_/_passing#02 - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, - "prometheus": [ - { - "name": "prom1", - "uri": "http://localhost", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "include": [ - "rules.yml" - ], - "required": false - } - ], "checks": { "enabled": [ + "alerts/annotation", + "alerts/count", + "alerts/external_labels", + "alerts/for", + "alerts/template", + "labels/conflict", + "promql/aggregate", + "alerts/comparison", + "promql/fragile", + "promql/range_query", + "promql/rate", + "promql/regexp", "promql/syntax", - "alerts/count" + "promql/vector_matching", + "query/cost", + "promql/series", + "rule/duplicate", + "rule/for", + "rule/label", + "rule/link", + "rule/reject" ] }, "rules": [ { - "ignore": [ + "match": [ { - "path": "rules.yml" + "keep_firing_for": "\u003e 15m" } ], - "alerts": { - "range": "1h", - "step": "1m", - "resolve": "5m" - } + "annotation": [ + { + "key": "summary", + "required": true + } + ] } ], "owners": {} } --- -[TestGetChecksForRule/for_match_/_passing - 1] +[TestGetChecksForRule/for_match_/_passing#03 - 1] { "ci": { "maxCommits": 20, @@ -1555,6 +1476,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1579,7 +1501,7 @@ { "match": [ { - "for": "\u003e 15m" + "keep_firing_for": "\u003e 15m" } ], "annotation": [ @@ -1594,7 +1516,7 @@ } --- -[TestGetChecksForRule/for_match_/_not_passing - 1] +[TestGetChecksForRule/for_match_/_recording_rules_/_not_passing - 1] { "ci": { "maxCommits": 20, @@ -1605,6 +1527,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1629,7 +1552,7 @@ { "match": [ { - "for": "\u003e 15m" + "for": "!= 15m" } ], "annotation": [ @@ -1644,7 +1567,7 @@ } --- -[TestGetChecksForRule/for_match_/_passing#01 - 1] +[TestGetChecksForRule/for_ignore_/_passing - 1] { "ci": { "maxCommits": 20, @@ -1655,6 +1578,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1677,9 +1601,9 @@ }, "rules": [ { - "match": [ + "ignore": [ { - "keep_firing_for": "\u003e 15m" + "for": "\u003c 15m" } ], "annotation": [ @@ -1694,7 +1618,7 @@ } --- -[TestGetChecksForRule/for_match_/_passing#02 - 1] +[TestGetChecksForRule/for_ignore_/_not_passing - 1] { "ci": { "maxCommits": 20, @@ -1705,6 +1629,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1727,9 +1652,9 @@ }, "rules": [ { - "match": [ + "ignore": [ { - "keep_firing_for": "\u003e 15m" + "for": "\u003c 15m" } ], "annotation": [ @@ -1744,7 +1669,7 @@ } --- -[TestGetChecksForRule/for_match_/_passing#03 - 1] +[TestGetChecksForRule/for_ignore_/_recording_rules_/_passing - 1] { "ci": { "maxCommits": 20, @@ -1755,6 +1680,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1777,9 +1703,9 @@ }, "rules": [ { - "match": [ + "ignore": [ { - "keep_firing_for": "\u003e 15m" + "for": "\u003e 0" } ], "annotation": [ @@ -1794,7 +1720,7 @@ } --- -[TestGetChecksForRule/for_match_/_recording_rules_/_not_passing - 1] +[TestGetChecksForRule/link - 1] { "ci": { "maxCommits": 20, @@ -1805,6 +1731,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1827,15 +1754,15 @@ }, "rules": [ { - "match": [ - { - "for": "!= 15m" - } - ], - "annotation": [ + "link": [ { - "key": "summary", - "required": true + "key": "https?://(.+)", + "uri": "http://localhost/$1", + "timeout": "10s", + "headers": { + "X-Auth": "xxx" + }, + "severity": "bug" } ] } @@ -1844,17 +1771,29 @@ } --- -[TestGetChecksForRule/for_ignore_/_passing - 1] +[TestGetChecksForRule/alerts/count_defaults - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, + "prometheus": [ + { + "name": "prom", + "uri": "http://localhost", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + } + ], "checks": { "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1877,34 +1816,40 @@ }, "rules": [ { - "ignore": [ - { - "for": "\u003c 15m" - } - ], - "annotation": [ - { - "key": "summary", - "required": true - } - ] + "alerts": { + "range": "1d", + "step": "1m", + "resolve": "5m" + } } ], "owners": {} } --- -[TestGetChecksForRule/for_ignore_/_not_passing - 1] +[TestGetChecksForRule/alerts/count_full - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, + "prometheus": [ + { + "name": "prom", + "uri": "http://localhost", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + } + ], "checks": { "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1927,34 +1872,86 @@ }, "rules": [ { - "ignore": [ - { - "for": "\u003c 15m" - } - ], - "annotation": [ - { - "key": "summary", - "required": true - } - ] + "alerts": { + "range": "1d", + "step": "1m", + "resolve": "5m", + "minCount": 100, + "severity": "bug" + } + } + ], + "owners": {} +} +--- + +[TestGetChecksForRule/single_check_enabled_via_config - 1] +{ + "ci": { + "maxCommits": 20, + "baseBranch": "master" + }, + "parser": {}, + "prometheus": [ + { + "name": "prom1", + "uri": "http://localhost", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "include": [ + "rules.yml" + ], + "required": false + } + ], + "checks": {}, + "rules": [ + { + "alerts": { + "range": "1h", + "step": "1m", + "resolve": "5m" + } } ], "owners": {} } --- -[TestGetChecksForRule/for_ignore_/_recording_rules_/_passing - 1] +[TestGetChecksForRule/two_prometheus_servers_/_snoozed_checks_via_comment - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, + "prometheus": [ + { + "name": "prom1", + "uri": "http://localhost/1", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + }, + { + "name": "prom2", + "uri": "http://localhost/2", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + } + ], "checks": { "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -1973,38 +1970,48 @@ "rule/label", "rule/link", "rule/reject" + ], + "disabled": [ + "alerts/template", + "promql/regexp" ] }, - "rules": [ - { - "ignore": [ - { - "for": "\u003e 0" - } - ], - "annotation": [ - { - "key": "summary", - "required": true - } - ] - } - ], "owners": {} } --- -[TestGetChecksForRule/link - 1] +[TestGetChecksForRule/two_prometheus_servers_/_expired_snooze - 1] { "ci": { "maxCommits": 20, "baseBranch": "master" }, "parser": {}, + "prometheus": [ + { + "name": "prom1", + "uri": "http://localhost/1", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + }, + { + "name": "prom2", + "uri": "http://localhost/2", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + } + ], "checks": { "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2023,28 +2030,17 @@ "rule/label", "rule/link", "rule/reject" + ], + "disabled": [ + "alerts/template", + "promql/regexp" ] }, - "rules": [ - { - "link": [ - { - "key": "https?://(.+)", - "uri": "http://localhost/$1", - "timeout": "10s", - "headers": { - "X-Auth": "xxx" - }, - "severity": "bug" - } - ] - } - ], "owners": {} } --- -[TestGetChecksForRule/two_prometheus_servers_/_disable_checks_via_file/disable_comment - 1] +[TestGetChecksForRule/checks_disabled_via_config - 1] { "ci": { "maxCommits": 20, @@ -2054,20 +2050,14 @@ "prometheus": [ { "name": "prom1", - "uri": "http://localhost/1", - "timeout": "1s", - "concurrency": 16, - "rateLimit": 100, - "uptime": "up", - "required": false - }, - { - "name": "prom2", - "uri": "http://localhost/2", + "uri": "http://localhost", "timeout": "1s", "concurrency": 16, "rateLimit": 100, "uptime": "up", + "include": [ + "rules.yml" + ], "required": false } ], @@ -2075,6 +2065,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2095,14 +2086,27 @@ "rule/reject" ], "disabled": [ - "alerts/template" + "promql/rate", + "promql/vector_matching", + "promql/range_query", + "rule/duplicate", + "labels/conflict" ] }, + "rules": [ + { + "alerts": { + "range": "1h", + "step": "1m", + "resolve": "5m" + } + } + ], "owners": {} } --- -[TestGetChecksForRule/two_prometheus_servers_/_snoozed_checks_via_comment - 1] +[TestGetChecksForRule/multiple_cost_checks - 1] { "ci": { "maxCommits": 20, @@ -2112,20 +2116,26 @@ "prometheus": [ { "name": "prom1", - "uri": "http://localhost/1", + "uri": "http://localhost", "timeout": "1s", "concurrency": 16, "rateLimit": 100, "uptime": "up", + "include": [ + "rules.yml" + ], "required": false }, { "name": "prom2", - "uri": "http://localhost/2", + "uri": "http://localhost", "timeout": "1s", "concurrency": 16, "rateLimit": 100, "uptime": "up", + "include": [ + "rules.yml" + ], "required": false } ], @@ -2133,6 +2143,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2151,17 +2162,32 @@ "rule/label", "rule/link", "rule/reject" - ], - "disabled": [ - "alerts/template", - "promql/regexp" ] }, + "rules": [ + { + "cost": { + "severity": "info" + } + }, + { + "cost": { + "maxSeries": 10000, + "severity": "warning" + } + }, + { + "cost": { + "maxSeries": 20000, + "severity": "bug" + } + } + ], "owners": {} } --- -[TestGetChecksForRule/two_prometheus_servers_/_expired_snooze - 1] +[TestGetChecksForRule/prometheus_check_with_prometheus_servers_and_disable_comment - 1] { "ci": { "maxCommits": 20, @@ -2171,20 +2197,26 @@ "prometheus": [ { "name": "prom1", - "uri": "http://localhost/1", + "uri": "http://localhost", "timeout": "1s", "concurrency": 16, "rateLimit": 100, "uptime": "up", + "include": [ + "rules.yml" + ], "required": false }, { "name": "prom2", - "uri": "http://localhost/2", + "uri": "http://localhost", "timeout": "1s", "concurrency": 16, "rateLimit": 100, "uptime": "up", + "include": [ + "rules.yml" + ], "required": false } ], @@ -2192,6 +2224,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2210,12 +2243,13 @@ "rule/label", "rule/link", "rule/reject" - ], - "disabled": [ - "alerts/template", - "promql/regexp" ] }, + "rules": [ + { + "cost": {} + } + ], "owners": {} } --- @@ -2268,6 +2302,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2340,6 +2375,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2364,7 +2400,7 @@ } --- -[TestGetChecksForRule/alerts/count_defaults - 1] +[TestGetChecksForRule/two_prometheus_servers_/_disable_all_checks_via_comment - 1] { "ci": { "maxCommits": 20, @@ -2373,8 +2409,17 @@ "parser": {}, "prometheus": [ { - "name": "prom", - "uri": "http://localhost", + "name": "prom1", + "uri": "http://localhost/1", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + }, + { + "name": "prom2", + "uri": "http://localhost/2", "timeout": "1s", "concurrency": 16, "rateLimit": 100, @@ -2386,6 +2431,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2404,22 +2450,17 @@ "rule/label", "rule/link", "rule/reject" + ], + "disabled": [ + "alerts/template", + "alerts/external_labels" ] }, - "rules": [ - { - "alerts": { - "range": "1d", - "step": "1m", - "resolve": "5m" - } - } - ], "owners": {} } --- -[TestGetChecksForRule/alerts/count_full - 1] +[TestGetChecksForRule/two_prometheus_servers_/_disable_checks_via_file/disable_comment - 1] { "ci": { "maxCommits": 20, @@ -2428,8 +2469,17 @@ "parser": {}, "prometheus": [ { - "name": "prom", - "uri": "http://localhost", + "name": "prom1", + "uri": "http://localhost/1", + "timeout": "1s", + "concurrency": 16, + "rateLimit": 100, + "uptime": "up", + "required": false + }, + { + "name": "prom2", + "uri": "http://localhost/2", "timeout": "1s", "concurrency": 16, "rateLimit": 100, @@ -2441,6 +2491,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2459,19 +2510,12 @@ "rule/label", "rule/link", "rule/reject" + ], + "disabled": [ + "alerts/template", + "alerts/external_labels" ] }, - "rules": [ - { - "alerts": { - "range": "1d", - "step": "1m", - "resolve": "5m", - "minCount": 100, - "severity": "bug" - } - } - ], "owners": {} } --- @@ -2487,6 +2531,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2533,6 +2578,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2583,6 +2629,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2638,6 +2685,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2658,7 +2706,8 @@ "rule/reject" ], "disabled": [ - "alerts/template" + "alerts/template", + "alerts/external_labels" ] }, "owners": {} @@ -2690,6 +2739,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2742,6 +2792,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2791,6 +2842,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2840,6 +2892,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2901,6 +2954,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2936,6 +2990,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -2974,6 +3029,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3030,6 +3086,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3086,6 +3143,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3155,6 +3213,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3195,6 +3254,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3301,6 +3361,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3355,6 +3416,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3410,6 +3472,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3466,6 +3529,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3522,6 +3586,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3578,6 +3643,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3634,6 +3700,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3690,6 +3757,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3746,6 +3814,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -3816,6 +3885,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4032,6 +4102,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4082,6 +4153,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4132,6 +4204,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4182,6 +4255,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4232,6 +4306,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4282,6 +4357,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4332,6 +4408,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4382,6 +4459,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4432,6 +4510,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4482,6 +4561,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4552,6 +4632,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4572,7 +4653,8 @@ "rule/reject" ], "disabled": [ - "alerts/template" + "alerts/template", + "alerts/external_labels" ] }, "owners": {} @@ -4610,6 +4692,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4669,6 +4752,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4745,6 +4829,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4817,6 +4902,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4863,6 +4949,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4918,6 +5005,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -4964,6 +5052,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5010,6 +5099,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5060,6 +5150,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5115,6 +5206,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5135,7 +5227,8 @@ "rule/reject" ], "disabled": [ - "alerts/template" + "alerts/template", + "alerts/external_labels" ] }, "owners": {} @@ -5167,6 +5260,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5219,6 +5313,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5268,6 +5363,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5317,6 +5413,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5378,6 +5475,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5413,6 +5511,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5451,6 +5550,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5507,6 +5607,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5563,6 +5664,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5632,6 +5734,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5672,6 +5775,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5778,6 +5882,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5832,6 +5937,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5887,6 +5993,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5943,6 +6050,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -5999,6 +6107,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6055,6 +6164,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6111,6 +6221,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6167,6 +6278,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6223,6 +6335,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6293,6 +6406,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6509,6 +6623,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6559,6 +6674,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6609,6 +6725,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6659,6 +6776,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6709,6 +6827,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6759,6 +6878,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6809,6 +6929,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6859,6 +6980,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6909,6 +7031,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -6959,6 +7082,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -7029,6 +7153,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -7049,7 +7174,8 @@ "rule/reject" ], "disabled": [ - "alerts/template" + "alerts/template", + "alerts/external_labels" ] }, "owners": {} @@ -7087,6 +7213,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -7146,6 +7273,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -7222,6 +7350,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -7294,6 +7423,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -7340,6 +7470,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", @@ -7395,6 +7526,7 @@ "enabled": [ "alerts/annotation", "alerts/count", + "alerts/external_labels", "alerts/for", "alerts/template", "labels/conflict", diff --git a/internal/config/config.go b/internal/config/config.go index 00ba9e11..3904badc 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -143,6 +143,11 @@ func (cfg *Config) GetChecksForRule(ctx context.Context, gen *PrometheusGenerato check: checks.NewLabelsConflictCheck(p), tags: p.Tags(), }) + allChecks = append(allChecks, checkMeta{ + name: checks.AlertsExternalLabelsCheckName, + check: checks.NewAlertsExternalLabelsCheck(p), + tags: p.Tags(), + }) } for _, rule := range cfg.Rules { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index d3465d71..ce826f42 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -188,6 +188,7 @@ prometheus "prom" { checks.RangeQueryCheckName + "(prom)", checks.RuleDuplicateCheckName + "(prom)", checks.LabelsConflictCheckName + "(prom)", + checks.AlertsExternalLabelsCheckName + "(prom)", }, }, { @@ -213,6 +214,7 @@ prometheus "prom" { checks.RangeQueryCheckName + "(prom)", checks.RuleDuplicateCheckName + "(prom)", checks.LabelsConflictCheckName + "(prom)", + checks.AlertsExternalLabelsCheckName + "(prom)", }, }, { @@ -227,7 +229,7 @@ prometheus "prom2" { timeout = "1s" } checks { - disabled = [ "alerts/template" ] + disabled = [ "alerts/template", "alerts/external_labels" ] } `, path: "rules.yml", @@ -333,6 +335,7 @@ prometheus "prom" { checks.RangeQueryCheckName + "(prom)", checks.RuleDuplicateCheckName + "(prom)", checks.LabelsConflictCheckName + "(prom)", + checks.AlertsExternalLabelsCheckName + "(prom)", }, }, { @@ -363,6 +366,7 @@ prometheus "ignore" { checks.RangeQueryCheckName + "(prom)", checks.RuleDuplicateCheckName + "(prom)", checks.LabelsConflictCheckName + "(prom)", + checks.AlertsExternalLabelsCheckName + "(prom)", }, }, { @@ -481,6 +485,7 @@ prometheus "prom2" { # pint disable promql/vector_matching(prom1) # pint disable rule/duplicate(prom1) # pint disable labels/conflict(prom2) + # pint disable alerts/external_labels(prom2) expr: sum(foo) `), checks: []string{ @@ -493,6 +498,7 @@ prometheus "prom2" { checks.RateCheckName + "(prom1)", checks.RangeQueryCheckName + "(prom1)", checks.LabelsConflictCheckName + "(prom1)", + checks.AlertsExternalLabelsCheckName + "(prom1)", checks.SeriesCheckName + "(prom2)", checks.VectorMatchingCheckName + "(prom2)", checks.RangeQueryCheckName + "(prom2)", @@ -587,6 +593,7 @@ rule { # pint disable promql/range_query # pint disable rule/duplicate # pint disable labels/conflict +# pint disable alerts/external_labels - record: foo # pint disable promql/fragile # pint disable promql/regexp @@ -871,6 +878,7 @@ prometheus "prom1" { checks.TemplateCheckName, checks.FragileCheckName, checks.RegexpCheckName, + checks.AlertsExternalLabelsCheckName + "(prom1)", checks.AlertsCheckName + "(prom1)", }, }, @@ -910,6 +918,7 @@ prometheus "prom1" { checks.RangeQueryCheckName + "(prom1)", checks.RuleDuplicateCheckName + "(prom1)", checks.LabelsConflictCheckName + "(prom1)", + checks.AlertsExternalLabelsCheckName + "(prom1)", checks.AlertsCheckName + "(prom1)", }, }, @@ -1263,7 +1272,7 @@ prometheus "prom2" { timeout = "1s" } checks { - disabled = [ "alerts/template" ] + disabled = [ "alerts/template", "alerts/external_labels" ] } `, path: "rules.yml", @@ -1318,8 +1327,10 @@ checks { checks.ComparisonCheckName, checks.FragileCheckName, checks.LabelsConflictCheckName + "(prom1)", + checks.AlertsExternalLabelsCheckName + "(prom1)", checks.SeriesCheckName + "(prom2)", checks.LabelsConflictCheckName + "(prom2)", + checks.AlertsExternalLabelsCheckName + "(prom2)", }, disabledChecks: []string{"promql/rate"}, }, @@ -1358,11 +1369,13 @@ checks { checks.RangeQueryCheckName + "(prom1)", checks.RuleDuplicateCheckName + "(prom1)", checks.LabelsConflictCheckName + "(prom1)", + checks.AlertsExternalLabelsCheckName + "(prom1)", checks.SeriesCheckName + "(prom2)", checks.VectorMatchingCheckName + "(prom2)", checks.RangeQueryCheckName + "(prom2)", checks.RuleDuplicateCheckName + "(prom2)", checks.LabelsConflictCheckName + "(prom2)", + checks.AlertsExternalLabelsCheckName + "(prom2)", }, disabledChecks: []string{"promql/rate"}, }, @@ -1385,6 +1398,7 @@ prometheus "prom3" { path: "rules.yml", rule: newRule(t, ` # pint disable alerts/count(+disable) +# pint disable alerts/external_labels(+disable) # pint disable labels/conflict(+disable) # pint disable promql/range_query(+disable) # pint disable promql/regexp(+disable) @@ -1407,12 +1421,14 @@ prometheus "prom3" { checks.RangeQueryCheckName + "(prom2)", checks.RuleDuplicateCheckName + "(prom2)", checks.LabelsConflictCheckName + "(prom2)", + checks.AlertsExternalLabelsCheckName + "(prom2)", checks.RateCheckName + "(prom3)", checks.SeriesCheckName + "(prom3)", checks.VectorMatchingCheckName + "(prom3)", checks.RangeQueryCheckName + "(prom3)", checks.RuleDuplicateCheckName + "(prom3)", checks.LabelsConflictCheckName + "(prom3)", + checks.AlertsExternalLabelsCheckName + "(prom3)", }, }, { @@ -1434,6 +1450,7 @@ prometheus "prom3" { path: "rules.yml", rule: newRule(t, ` # pint snooze 2099-11-28 alerts/count(+disable) +# pint snooze 2099-11-28 alerts/external_labels(+disable) # pint snooze 2099-11-28 labels/conflict(+disable) # pint snooze 2099-11-28 promql/range_query(+disable) # pint snooze 2099-11-28 promql/regexp(+disable) @@ -1456,12 +1473,14 @@ prometheus "prom3" { checks.RangeQueryCheckName + "(prom2)", checks.RuleDuplicateCheckName + "(prom2)", checks.LabelsConflictCheckName + "(prom2)", + checks.AlertsExternalLabelsCheckName + "(prom2)", checks.RateCheckName + "(prom3)", checks.SeriesCheckName + "(prom3)", checks.VectorMatchingCheckName + "(prom3)", checks.RangeQueryCheckName + "(prom3)", checks.RuleDuplicateCheckName + "(prom3)", checks.LabelsConflictCheckName + "(prom3)", + checks.AlertsExternalLabelsCheckName + "(prom3)", }, }, { @@ -1494,6 +1513,7 @@ rule { checks.RangeQueryCheckName + "(prom)", checks.RuleDuplicateCheckName + "(prom)", checks.LabelsConflictCheckName + "(prom)", + checks.AlertsExternalLabelsCheckName + "(prom)", checks.AlertsCheckName + "(prom)", }, }, @@ -1529,6 +1549,7 @@ rule { checks.RangeQueryCheckName + "(prom)", checks.RuleDuplicateCheckName + "(prom)", checks.LabelsConflictCheckName + "(prom)", + checks.AlertsExternalLabelsCheckName + "(prom)", checks.AlertsCheckName + "(prom)", }, },