Skip to content

Commit dcb1c2e

Browse files
committed
Fix ExternalLabels() for Prometheus v3.0
Prometheus v3.0.0-rc.0 introduces a new scrape protocol (`PrometheusText1.0.0`) which is present by default in the global configuration. It breaks the Thanos sidecar when it wants to retrieve the external labels. This change replaces the use of the Prometheus `GlobalConfig` struct by a minimal struct which unmarshals only the `external_labels` key. Signed-off-by: Simon Pasquier <[email protected]>
1 parent 928bc7a commit dcb1c2e

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

pkg/promclient/promclient.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"github.com/pkg/errors"
2828
"github.com/prometheus/common/expfmt"
2929
"github.com/prometheus/common/model"
30-
"github.com/prometheus/prometheus/config"
3130
"github.com/prometheus/prometheus/model/labels"
3231
"github.com/prometheus/prometheus/model/timestamp"
3332
"github.com/prometheus/prometheus/promql"
@@ -201,13 +200,15 @@ func (c *Client) ExternalLabels(ctx context.Context, base *url.URL) (labels.Labe
201200
return labels.EmptyLabels(), errors.Wrapf(err, "unmarshal response: %v", string(body))
202201
}
203202
var cfg struct {
204-
GlobalConfig config.GlobalConfig `yaml:"global"`
203+
GlobalConfig struct {
204+
ExternalLabels map[string]string `yaml:"external_labels"`
205+
} `yaml:"global"`
205206
}
206207
if err := yaml.Unmarshal([]byte(d.Data.YAML), &cfg); err != nil {
207208
return labels.EmptyLabels(), errors.Wrapf(err, "parse Prometheus config: %v", d.Data.YAML)
208209
}
209210

210-
return cfg.GlobalConfig.ExternalLabels, nil
211+
return labels.FromMap(cfg.GlobalConfig.ExternalLabels), nil
211212
}
212213

213214
type Flags struct {

pkg/promclient/promclient_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) The Thanos Authors.
2+
// Licensed under the Apache License 2.0.
3+
4+
// Package promclient offers helper client function for various API endpoints.
5+
6+
package promclient
7+
8+
import (
9+
"context"
10+
"fmt"
11+
"net/http"
12+
"net/http/httptest"
13+
"net/url"
14+
"testing"
15+
16+
"github.com/efficientgo/core/testutil"
17+
)
18+
19+
func TestExternalLabels(t *testing.T) {
20+
for _, tc := range []struct {
21+
name string
22+
response string
23+
err bool
24+
labels map[string]string
25+
}{
26+
{
27+
name: "invalid payload",
28+
response: `{`,
29+
err: true,
30+
},
31+
{
32+
name: "unknown scrape protocol",
33+
response: `{"status":"success","data":{"yaml":"global:\n scrape_interval: 1m\n scrape_timeout: 10s\n scrape_protocols:\n - OpenMetricsText1.0.0\n - OpenMetricsText0.0.1\n - PrometheusText1.0.0\n - PrometheusText0.0.4\n - UnknownScrapeProto\n evaluation_interval: 1m\n external_labels:\n az: \"1\"\n region: eu-west\nruntime:\n gogc: 75\n"}}`,
34+
labels: map[string]string{
35+
"region": "eu-west",
36+
"az": "1",
37+
},
38+
},
39+
{
40+
name: "no external labels",
41+
response: `{"status":"success","data":{"yaml":"global:\n scrape_interval: 1m\n scrape_timeout: 10s\n scrape_protocols:\n - OpenMetricsText1.0.0\n - OpenMetricsText0.0.1\n - PrometheusText1.0.0\n - PrometheusText0.0.4\n - UnknownScrapeProto\n evaluation_interval: 1m\nruntime:\n gogc: 75\n"}}`,
42+
labels: map[string]string{},
43+
},
44+
} {
45+
t.Run(tc.name, func(t *testing.T) {
46+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
47+
fmt.Fprintln(w, tc.response)
48+
}))
49+
defer ts.Close()
50+
51+
u, err := url.Parse(ts.URL)
52+
testutil.Ok(t, err)
53+
54+
ext, err := NewDefaultClient().ExternalLabels(context.Background(), u)
55+
if tc.err {
56+
testutil.NotOk(t, err)
57+
return
58+
}
59+
60+
testutil.Ok(t, err)
61+
testutil.Equals(t, len(tc.labels), ext.Len())
62+
for k, v := range tc.labels {
63+
testutil.Equals(t, v, ext.Get(k))
64+
}
65+
})
66+
}
67+
}

0 commit comments

Comments
 (0)