From 7c0801a926b5a5e52f7ffd1d6c45ef2f78cf09c0 Mon Sep 17 00:00:00 2001 From: Hoa Date: Wed, 1 Apr 2026 17:02:20 +0800 Subject: [PATCH] promtool: add --header flag to query instant command The `--header` flag was already supported by `promtool query range` but was missing from `promtool query instant`. This adds the same flag so users can pass extra HTTP headers (e.g. `X-Scope-OrgID` for multi-tenant setups) without needing to create an `--http.config.file`. ``` [ENHANCEMENT] promtool: Add `--header` flag to `query instant` command, matching existing `query range` behaviour. ``` Signed-off-by: Hoa --- cmd/promtool/main.go | 3 ++- cmd/promtool/main_test.go | 18 +++++++++++++++++- cmd/promtool/query.go | 4 ++-- docs/command-line/promtool.md | 1 + 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/cmd/promtool/main.go b/cmd/promtool/main.go index 6555ccc6fa..6b897ba1ae 100644 --- a/cmd/promtool/main.go +++ b/cmd/promtool/main.go @@ -180,6 +180,7 @@ func main() { queryInstantCmd.Arg("server", "Prometheus server to query.").Required().URLVar(&serverURL) queryInstantExpr := queryInstantCmd.Arg("expr", "PromQL query expression.").Required().String() queryInstantTime := queryInstantCmd.Flag("time", "Query evaluation time (RFC3339 or Unix timestamp).").String() + queryInstantHeaders := queryInstantCmd.Flag("header", "Extra headers to send to server.").StringMap() queryRangeCmd := queryCmd.Command("range", "Run range query.") queryRangeCmd.Arg("server", "Prometheus server to query.").Required().URLVar(&serverURL) @@ -393,7 +394,7 @@ func main() { os.Exit(PushMetrics(remoteWriteURL, httpRoundTripper, *pushMetricsHeaders, *pushMetricsTimeout, *pushMetricsProtoMsg, *pushMetricsLabels, *metricFiles...)) case queryInstantCmd.FullCommand(): - os.Exit(QueryInstant(serverURL, httpRoundTripper, *queryInstantExpr, *queryInstantTime, p)) + os.Exit(QueryInstant(serverURL, httpRoundTripper, *queryInstantHeaders, *queryInstantExpr, *queryInstantTime, p)) case queryRangeCmd.FullCommand(): os.Exit(QueryRange(serverURL, httpRoundTripper, *queryRangeHeaders, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep, p)) diff --git a/cmd/promtool/main_test.go b/cmd/promtool/main_test.go index 297dd35d70..bbc52355a9 100644 --- a/cmd/promtool/main_test.go +++ b/cmd/promtool/main_test.go @@ -95,7 +95,7 @@ func TestQueryInstant(t *testing.T) { require.NoError(t, err) p := &promqlPrinter{} - exitCode := QueryInstant(urlObject, http.DefaultTransport, "up", "300", p) + exitCode := QueryInstant(urlObject, http.DefaultTransport, map[string]string{}, "up", "300", p) require.Equal(t, "/api/v1/query", getRequest().URL.Path) form := getRequest().Form require.Equal(t, "up", form.Get("query")) @@ -103,6 +103,22 @@ func TestQueryInstant(t *testing.T) { require.Equal(t, 0, exitCode) } +func TestQueryInstantHeaders(t *testing.T) { + t.Parallel() + s, getRequest := mockServer(200, `{"status": "success", "data": {"resultType": "vector", "result": []}}`) + defer s.Close() + + urlObject, err := url.Parse(s.URL) + require.NoError(t, err) + + p := &promqlPrinter{} + headers := map[string]string{"X-Scope-OrgID": "prom", "X-Custom": "value"} + exitCode := QueryInstant(urlObject, http.DefaultTransport, headers, "up", "300", p) + require.Equal(t, 0, exitCode) + require.Equal(t, "prom", getRequest().Header.Get("X-Scope-OrgID")) + require.Equal(t, "value", getRequest().Header.Get("X-Custom")) +} + func mockServer(code int, body string) (*httptest.Server, func() *http.Request) { var req *http.Request server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/promtool/query.go b/cmd/promtool/query.go index 1342f148f8..ef0a2368ef 100644 --- a/cmd/promtool/query.go +++ b/cmd/promtool/query.go @@ -61,8 +61,8 @@ func newAPI(url *url.URL, roundTripper http.RoundTripper, headers map[string]str } // QueryInstant performs an instant query against a Prometheus server. -func QueryInstant(url *url.URL, roundTripper http.RoundTripper, query, evalTime string, p printer) int { - api, err := newAPI(url, roundTripper, nil) +func QueryInstant(url *url.URL, roundTripper http.RoundTripper, headers map[string]string, query, evalTime string, p printer) int { + api, err := newAPI(url, roundTripper, headers) if err != nil { fmt.Fprintln(os.Stderr, "error creating API client:", err) return failureExitCode diff --git a/docs/command-line/promtool.md b/docs/command-line/promtool.md index e8ffa75aaa..28a0d99696 100644 --- a/docs/command-line/promtool.md +++ b/docs/command-line/promtool.md @@ -240,6 +240,7 @@ Run instant query. | Flag | Description | | --- | --- | | --time | Query evaluation time (RFC3339 or Unix timestamp). | +| --header | Extra headers to send to server. |