Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store API paths in one place #1238

Merged
merged 1 commit into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions cmd/pint/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/cloudflare/pint/internal/git"
"github.com/cloudflare/pint/internal/log"
"github.com/cloudflare/pint/internal/parser"
"github.com/cloudflare/pint/internal/promapi"
)

func BenchmarkFindEntries(b *testing.B) {
Expand Down Expand Up @@ -50,23 +51,23 @@ func BenchmarkCheckRules(b *testing.B) {

srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v1/status/config":
case promapi.APIPathConfig:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n scrape_interval: 30s\n"}}`))
case "/api/v1/status/flags":
case promapi.APIPathFlags:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"storage.tsdb.retention.time": "1d"}}`))
case "/api/v1/metadata":
case promapi.APIPathMetadata:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{}}`))
case "/api/v1/query":
case promapi.APIPathQuery:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"resultType":"vector","result":[]}}`))
case "/api/v1/query_range":
case promapi.APIPathQueryRange:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"resultType":"matrix","result":[]}}`))
Expand Down
10 changes: 5 additions & 5 deletions internal/checks/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,11 @@ func (fc formCond) isMatch(r *http.Request) bool {
}

var (
requireConfigPath = requestPathCond{path: "/api/v1/status/config"}
requireFlagsPath = requestPathCond{path: "/api/v1/status/flags"}
requireQueryPath = requestPathCond{path: "/api/v1/query"}
requireRangeQueryPath = requestPathCond{path: "/api/v1/query_range"}
requireMetadataPath = requestPathCond{path: "/api/v1/metadata"}
requireConfigPath = requestPathCond{path: promapi.APIPathConfig}
requireFlagsPath = requestPathCond{path: promapi.APIPathFlags}
requireQueryPath = requestPathCond{path: promapi.APIPathQuery}
requireRangeQueryPath = requestPathCond{path: promapi.APIPathQueryRange}
requireMetadataPath = requestPathCond{path: promapi.APIPathMetadata}
)

type promError struct {
Expand Down
10 changes: 5 additions & 5 deletions internal/checks/promql_series_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3975,7 +3975,7 @@ func TestSeriesCheck(t *testing.T) {
},
mocks: []*prometheusMock{
{
conds: []requestCondition{requestPathCond{path: "/other/api/v1/query"}},
conds: []requestCondition{requestPathCond{path: "/other" + promapi.APIPathQuery}},
resp: respondWithEmptyVector(),
},
{
Expand Down Expand Up @@ -4016,7 +4016,7 @@ func TestSeriesCheck(t *testing.T) {
},
mocks: []*prometheusMock{
{
conds: []requestCondition{requestPathCond{path: "/other/api/v1/query"}},
conds: []requestCondition{requestPathCond{path: "/other" + promapi.APIPathQuery}},
resp: respondWithSingleInstantVector(),
},
{
Expand Down Expand Up @@ -4057,7 +4057,7 @@ func TestSeriesCheck(t *testing.T) {
},
mocks: []*prometheusMock{
{
conds: []requestCondition{requestPathCond{path: "/other/api/v1/query"}},
conds: []requestCondition{requestPathCond{path: "/other" + promapi.APIPathQuery}},
resp: respondWithSingleInstantVector(),
},
{
Expand Down Expand Up @@ -4108,7 +4108,7 @@ func TestSeriesCheck(t *testing.T) {
},
mocks: []*prometheusMock{
{
conds: []requestCondition{requestPathCond{path: "/other/api/v1/query"}},
conds: []requestCondition{requestPathCond{path: "/other" + promapi.APIPathQuery}},
resp: sleepResponse{
sleep: time.Millisecond * 20,
resp: respondWithSingleInstantVector(),
Expand Down Expand Up @@ -4163,7 +4163,7 @@ func TestSeriesCheck(t *testing.T) {
},
mocks: []*prometheusMock{
{
conds: []requestCondition{requestPathCond{path: "/other/api/v1/query"}},
conds: []requestCondition{requestPathCond{path: "/other" + promapi.APIPathQuery}},
resp: sleepResponse{
sleep: time.Millisecond * 230,
resp: respondWithSingleInstantVector(),
Expand Down
15 changes: 9 additions & 6 deletions internal/promapi/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import (
"gopkg.in/yaml.v3"
)

const (
APIPathConfig = "/api/v1/status/config"
)

type ConfigSectionGlobal struct {
ExternalLabels map[string]string `yaml:"external_labels"`
ScrapeInterval time.Duration `yaml:"scrape_interval"`
Expand Down Expand Up @@ -62,18 +66,18 @@ func (q configQuery) Run() queryResult {

qr.value, err = streamConfig(resp.Body)
if err != nil {
prometheusQueryErrorsTotal.WithLabelValues(q.prom.name, "/api/v1/status/config", errReason(err)).Inc()
prometheusQueryErrorsTotal.WithLabelValues(q.prom.name, APIPathConfig, errReason(err)).Inc()
qr.err = fmt.Errorf("failed to decode config data in %s response: %w", q.prom.safeURI, err)
}
return qr
}

func (q configQuery) Endpoint() string {
return "/api/v1/status/config"
return APIPathConfig
}

func (q configQuery) String() string {
return "/api/v1/status/config"
return APIPathConfig
}

func (q configQuery) CacheKey() uint64 {
Expand All @@ -87,9 +91,8 @@ func (q configQuery) CacheTTL() time.Duration {
func (p *Prometheus) Config(ctx context.Context, cacheTTL time.Duration) (*ConfigResult, error) {
slog.Debug("Scheduling Prometheus configuration query", slog.String("uri", p.safeURI))

key := "/api/v1/status/config"
p.locker.lock(key)
defer p.locker.unlock(key)
p.locker.lock(APIPathConfig)
defer p.locker.unlock(APIPathConfig)

if cacheTTL == 0 {
cacheTTL = time.Minute
Expand Down
14 changes: 7 additions & 7 deletions internal/promapi/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,31 @@ import (
func TestConfig(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/30s/api/v1/status/config":
case "/30s" + promapi.APIPathConfig:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n scrape_interval: 30s\n"}}`))
case "/1m/api/v1/status/config":
case "/1m" + promapi.APIPathConfig:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n scrape_interval: 1m\n"}}`))
case "/default/api/v1/status/config":
case "/default" + promapi.APIPathConfig:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n {}\n"}}`))
case "/once/api/v1/status/config":
case "/once" + promapi.APIPathConfig:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n {}\n"}}`))
case "/slow/api/v1/status/config":
case "/slow" + promapi.APIPathConfig:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
time.Sleep(time.Second * 2)
_, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"global:\n {}\n"}}`))
case "/error/api/v1/status/config":
case "/error" + promapi.APIPathConfig:
w.WriteHeader(500)
_, _ = w.Write([]byte("fake error\n"))
case "/badYaml/api/v1/status/config":
case "/badYaml" + promapi.APIPathConfig:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"yaml":"invalid yaml"}}`))
Expand Down
13 changes: 8 additions & 5 deletions internal/promapi/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
"github.com/prymitive/current"
)

const (
APIPathFlags = "/api/v1/status/flags"
)

type FlagsResult struct {
Flags v1.FlagsResult
URI string
Expand Down Expand Up @@ -52,11 +56,11 @@ func (q flagsQuery) Run() queryResult {
}

func (q flagsQuery) Endpoint() string {
return "/api/v1/status/flags"
return APIPathFlags
}

func (q flagsQuery) String() string {
return "/api/v1/status/flags"
return APIPathFlags
}

func (q flagsQuery) CacheKey() uint64 {
Expand All @@ -70,9 +74,8 @@ func (q flagsQuery) CacheTTL() time.Duration {
func (p *Prometheus) Flags(ctx context.Context) (*FlagsResult, error) {
slog.Debug("Scheduling Prometheus flags query", slog.String("uri", p.safeURI))

key := "/api/v1/status/flags"
p.locker.lock(key)
defer p.locker.unlock(key)
p.locker.lock(APIPathFlags)
defer p.locker.unlock(APIPathFlags)

resultChan := make(chan queryResult)
p.queries <- queryRequest{
Expand Down
12 changes: 6 additions & 6 deletions internal/promapi/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,27 @@ import (
func TestFlags(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/default/api/v1/status/flags":
case "/default" + promapi.APIPathFlags:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{}}`))
case "/foo/api/v1/status/flags":
case "/foo" + promapi.APIPathFlags:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"foo":"bar"}}`))
case "/once/api/v1/status/flags":
case "/once" + promapi.APIPathFlags:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{}}`))
case "/slow/api/v1/status/flags":
case "/slow" + promapi.APIPathFlags:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
time.Sleep(time.Second * 2)
_, _ = w.Write([]byte(`{"status":"success","data":{}}`))
case "/error/api/v1/status/flags":
case "/error" + promapi.APIPathFlags:
w.WriteHeader(500)
_, _ = w.Write([]byte("fake error\n"))
case "/badYaml/api/v1/status/flags":
case "/badYaml" + promapi.APIPathFlags:
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"success","data":{"xxx"}}`))
Expand Down
8 changes: 6 additions & 2 deletions internal/promapi/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
"github.com/prymitive/current"
)

const (
APIPathMetadata = "/api/v1/metadata"
)

type MetadataResult struct {
URI string
Metadata []v1.Metadata
Expand Down Expand Up @@ -58,7 +62,7 @@ func (q metadataQuery) Run() queryResult {
}

func (q metadataQuery) Endpoint() string {
return "/api/v1/metadata"
return APIPathMetadata
}

func (q metadataQuery) String() string {
Expand All @@ -76,7 +80,7 @@ func (q metadataQuery) CacheTTL() time.Duration {
func (p *Prometheus) Metadata(ctx context.Context, metric string) (*MetadataResult, error) {
slog.Debug("Scheduling Prometheus metrics metadata query", slog.String("uri", p.safeURI), slog.String("metric", metric))

key := "/api/v1/metadata/" + metric
key := APIPathMetadata + metric
p.locker.lock(key)
defer p.locker.unlock(key)

Expand Down
8 changes: 6 additions & 2 deletions internal/promapi/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import (
"github.com/prymitive/current"
)

const (
APIPathQuery = "/api/v1/query"
)

type QueryResult struct {
URI string
Series []Sample
Expand Down Expand Up @@ -63,7 +67,7 @@ func (q instantQuery) Run() queryResult {
}

func (q instantQuery) Endpoint() string {
return "/api/v1/query"
return APIPathQuery
}

func (q instantQuery) String() string {
Expand All @@ -81,7 +85,7 @@ func (q instantQuery) CacheTTL() time.Duration {
func (p *Prometheus) Query(ctx context.Context, expr string) (*QueryResult, error) {
slog.Debug("Scheduling prometheus query", slog.String("uri", p.safeURI), slog.String("query", expr))

key := "/api/v1/query/" + expr
key := APIPathQuery + expr
p.locker.lock(key)
defer p.locker.unlock(key)

Expand Down
8 changes: 6 additions & 2 deletions internal/promapi/range.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (
"github.com/cloudflare/pint/internal/output"
)

const (
APIPathQueryRange = "/api/v1/query_range"
)

type RangeQueryResult struct {
URI string
Series SeriesTimeRanges
Expand Down Expand Up @@ -69,7 +73,7 @@ func (q rangeQuery) Run() queryResult {
}

func (q rangeQuery) Endpoint() string {
return "/api/v1/query_range"
return APIPathQueryRange
}

func (q rangeQuery) String() string {
Expand Down Expand Up @@ -116,7 +120,7 @@ func (p *Prometheus) RangeQuery(ctx context.Context, expr string, params RangeQu
slog.Int("slices", len(slices)),
)

key := fmt.Sprintf("/api/v1/query_range/%s/%s", expr, params.String())
key := fmt.Sprintf("%s/%s/%s", APIPathQueryRange, expr, params.String())
p.locker.lock(key)
defer p.locker.unlock(key)

Expand Down
Loading