Skip to content

Commit

Permalink
Merge pull request #1246 from cloudflare/apis
Browse files Browse the repository at this point in the history
Make sure query and range query APIs are always required
  • Loading branch information
prymitive authored Jan 6, 2025
2 parents e345506 + 2c7d7eb commit 0aae64c
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 19 deletions.
6 changes: 3 additions & 3 deletions cmd/pint/tests/0054_watch_metrics_prometheus.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,15 @@ pint_last_run_time_seconds
# TYPE pint_problem gauge
pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/counter\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/counter",severity="bug"}
pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/range_query\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/range_query",severity="bug"}
pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/rate\" checks due to `prom1` Prometheus server at http://127.0.0.1:7054 connection error: `server_error: server error: 500`.",reporter="promql/rate",severity="bug"}
pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/rate\" checks due to `prom1` Prometheus server at http://127.0.0.1:7054 connection error: `server_error: 500 Internal Server Error`.",reporter="promql/rate",severity="bug"}
pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/rate\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/rate",severity="bug"}
pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/series\" checks due to `prom2` Prometheus server 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="`prom1` Prometheus server 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="Prometheus failed to parse the query with this PromQL 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 `prom1` Prometheus server 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 `prom1` Prometheus server at http://127.0.0.1:7054 connection error: `server_error: 500 Internal Server Error`.",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 `prom2` Prometheus server 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 `prom2` Prometheus server 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 `prom1` Prometheus server 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 `prom1` Prometheus server at http://127.0.0.1:7054 connection error: `server_error: 500 Internal Server Error`.",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 `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/rate",severity="bug"}
pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="Couldn't run \"promql/series\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/series",severity="bug"}
pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="`prom1` Prometheus server at http://127.0.0.1:7054 failed with: `bad_data: bogus query`.",reporter="promql/series",severity="bug"}
Expand Down
4 changes: 2 additions & 2 deletions cmd/pint/tests/0056_prometheus_required.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ http start prometheus 127.0.0.1:7056

exec pint -l debug --no-color lint rules
! stdout .
stderr 'level=ERROR msg="Query returned an error" err="server error: 500" uri=http://127.0.0.1:7056 query=count\(up\)'
stderr 'level=ERROR msg="Query returned an error" err="server error: 500" uri=http://127.0.0.1:7056 query=/api/v1/status/config'
stderr 'level=ERROR msg="Query returned an error" err="500 Internal Server Error" uri=http://127.0.0.1:7056 query=count\(up\)'
stderr 'level=ERROR msg="Query returned an error" err="500 Internal Server Error" uri=http://127.0.0.1:7056 query=/api/v1/status/config'
stderr 'level=INFO msg="Problems found" Warning=[0-9]+'

-- rules/1.yaml --
Expand Down
6 changes: 3 additions & 3 deletions cmd/pint/tests/0104_file_ignore_prom.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ http start prometheus 127.0.0.1:7104

! exec pint --no-color lint rules
! stdout .
stderr 'level=ERROR msg="Query returned an error" err="server error: 502" uri=http://127.0.0.1:7104 query=/api/v1/status/config'
stderr 'level=ERROR msg="Query returned an error" err="server error: 502" uri=http://127.0.0.1:7104 query=/api/v1/status/flags'
stderr 'level=ERROR msg="Query returned an error" err="server error: 502" uri=http://127.0.0.1:7104 query=count\(foo\)'
stderr 'level=ERROR msg="Query returned an error" err="502 Bad Gateway" uri=http://127.0.0.1:7104 query=/api/v1/status/config'
stderr 'level=ERROR msg="Query returned an error" err="502 Bad Gateway" uri=http://127.0.0.1:7104 query=/api/v1/status/flags'
stderr 'level=ERROR msg="Query returned an error" err="502 Bad Gateway" uri=http://127.0.0.1:7104 query=count\(foo\)'
stderr 'level=INFO msg="Problems found" Bug=3'
-- rules/0001.yml --
# This should skip all online checks
Expand Down
55 changes: 55 additions & 0 deletions internal/checks/promql_series_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package checks_test
import (
"context"
"fmt"
"net/http"
"testing"
"time"

Expand Down Expand Up @@ -4179,6 +4180,60 @@ func TestSeriesCheck(t *testing.T) {
},
},
},
{
description: "unsupported query",
content: "- record: foo\n expr: sum(foo)\n",
checker: newSeriesCheck,
prometheus: newSimpleProm,
problems: func(uri string) []checks.Problem {
return []checks.Problem{
{
Lines: parser.LineRange{
First: 2,
Last: 2,
},
Reporter: checks.SeriesCheckName,
Text: checkErrorBadData("prom", uri, "client_error: 404 Not Found"),
Severity: checks.Bug,
},
}
},
mocks: []*prometheusMock{
{
conds: []requestCondition{requireQueryPath},
resp: httpResponse{code: http.StatusNotFound, body: "Not Found"},
},
},
},
{
description: "unsupported range query",
content: "- record: foo\n expr: sum(foo)\n",
checker: newSeriesCheck,
prometheus: newSimpleProm,
problems: func(uri string) []checks.Problem {
return []checks.Problem{
{
Lines: parser.LineRange{
First: 2,
Last: 2,
},
Reporter: checks.SeriesCheckName,
Text: checkErrorBadData("prom", uri, "client_error: 404 Not Found"),
Severity: checks.Bug,
},
}
},
mocks: []*prometheusMock{
{
conds: []requestCondition{requireQueryPath},
resp: respondWithEmptyVector(),
},
{
conds: []requestCondition{requireRangeQueryPath},
resp: httpResponse{code: http.StatusNotFound, body: "Not Found"},
},
},
},
}
runTests(t, testCases)
}
2 changes: 1 addition & 1 deletion internal/promapi/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func TestConfig(t *testing.T) {
{
prefix: "/error",
timeout: time.Second,
err: "server_error: server error: 500",
err: "server_error: 500 Internal Server Error",
},
{
prefix: "/badYaml",
Expand Down
27 changes: 19 additions & 8 deletions internal/promapi/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,25 @@ func tryDecodingAPIError(resp *http.Response) error {
slog.Debug("Trying to parse Prometheus error response", slog.Int("code", resp.StatusCode))

if resp.StatusCode == http.StatusNotFound {
apiPath := "some API endpoints"
var apiPath string
msg := "some API endpoints"
if resp.Request != nil {
apiPath = "`" + resp.Request.URL.Path + "` API endpoint"
switch {
case strings.HasSuffix(resp.Request.URL.Path, APIPathConfig):
apiPath = APIPathConfig
case strings.HasSuffix(resp.Request.URL.Path, APIPathFlags):
apiPath = APIPathFlags
case strings.HasSuffix(resp.Request.URL.Path, APIPathMetadata):
apiPath = APIPathMetadata
}
msg = "`" + apiPath + "` API endpoint"
}
return APIError{
Status: "",
ErrorType: ErrAPIUnsupported,
Err: "this server doesn't seem to support " + apiPath,
if apiPath != "" {
return APIError{
Status: "",
ErrorType: ErrAPIUnsupported,
Err: "this server doesn't seem to support " + msg,
}
}
}

Expand All @@ -143,9 +154,9 @@ func tryDecodingAPIError(resp *http.Response) error {
if err := decoder.Stream(dec); err != nil {
switch resp.StatusCode / 100 {
case 4:
return APIError{Status: "error", ErrorType: v1.ErrClient, Err: fmt.Sprintf("client error: %d", resp.StatusCode)}
return APIError{Status: "error", ErrorType: v1.ErrClient, Err: resp.Status}
case 5:
return APIError{Status: "error", ErrorType: v1.ErrServer, Err: fmt.Sprintf("server error: %d", resp.StatusCode)}
return APIError{Status: "error", ErrorType: v1.ErrServer, Err: resp.Status}
}
return APIError{Status: "error", ErrorType: v1.ErrBadResponse, Err: fmt.Sprintf("bad response code: %d", resp.StatusCode)}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/promapi/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestFlags(t *testing.T) {
{
prefix: "/error",
timeout: time.Second,
err: "server_error: server error: 500",
err: "server_error: 500 Internal Server Error",
},
{
prefix: "/badYaml",
Expand Down
2 changes: 1 addition & 1 deletion internal/promapi/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestMetadata(t *testing.T) {
{
metric: "error",
timeout: time.Second,
err: "server_error: server error: 500",
err: "server_error: 500 Internal Server Error",
},
{
metric: "once",
Expand Down

0 comments on commit 0aae64c

Please sign in to comment.