Skip to content

Commit 8e86366

Browse files
authored
Merge pull request #1637 from ta924/matrixpanic
block panic when prom returns range vector
2 parents 04f5c68 + e5dfbf4 commit 8e86366

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

pkg/metrics/providers/errors.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ package providers
1919
import "errors"
2020

2121
var (
22-
ErrNoValuesFound = errors.New("no values found")
22+
ErrNoValuesFound = errors.New("no values found")
23+
ErrMultipleValuesReturned = errors.New("query returned multiple values")
2324
)

pkg/metrics/providers/prometheus.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ type prometheusResponse struct {
5151
Metric struct {
5252
Name string `json:"name"`
5353
}
54-
Value []interface{} `json:"value"`
54+
Value []interface{} `json:"value"`
55+
Values []interface{} `json:"values"`
5556
}
5657
}
5758
}
@@ -147,6 +148,9 @@ func (p *PrometheusProvider) RunQuery(query string) (float64, error) {
147148

148149
var value *float64
149150
for _, v := range result.Data.Result {
151+
if v.Values != nil {
152+
return 0, fmt.Errorf("%w", ErrMultipleValuesReturned)
153+
}
150154
metricValue := v.Value[1]
151155
switch metricValue.(type) {
152156
case string:

pkg/metrics/providers/prometheus_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,39 @@ func TestPrometheusProvider_RunQueryWithBasicAuth(t *testing.T) {
180180
})
181181
}
182182

183+
multipleResultTests := []struct {
184+
name string
185+
queryResult string
186+
}{
187+
{name: "values instead of value", queryResult: `{"status": "success","data": {"resultType": "matrix","result": [{"metric": {"__name__": "processTime_seconds:avg"},"values": [[1714404069.294,"NaN"],[1714404071.3,"NaN"],[1714404099.294,"NaN"],[1714404101.3,"NaN"]]},{"metric": {"__name__": "processTime_seconds:avg"},"values": [[1714404069.294,"NaN"],[1714404071.3,"NaN"],[1714404099.294,"NaN"],[1714404101.3,"NaN"]]}]}}`},
188+
}
189+
190+
for _, tt := range multipleResultTests {
191+
t.Run(tt.name, func(t *testing.T) {
192+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
193+
json := tt.queryResult
194+
w.Write([]byte(json))
195+
}))
196+
defer ts.Close()
197+
198+
clients := prometheusFake()
199+
200+
template, err := clients.flaggerClient.FlaggerV1beta1().
201+
MetricTemplates("default").Get(context.TODO(), "prometheus", metav1.GetOptions{})
202+
require.NoError(t, err)
203+
template.Spec.Provider.Address = ts.URL
204+
205+
secret, err := clients.kubeClient.CoreV1().Secrets("default").Get(context.TODO(), "prometheus", metav1.GetOptions{})
206+
require.NoError(t, err)
207+
208+
prom, err := NewPrometheusProvider(template.Spec.Provider, secret.Data)
209+
require.NoError(t, err)
210+
211+
_, err = prom.RunQuery(template.Spec.Query)
212+
require.True(t, errors.Is(err, ErrMultipleValuesReturned))
213+
})
214+
}
215+
183216
}
184217

185218
func TestPrometheusProvider_RunQueryWithBearerAuth(t *testing.T) {

0 commit comments

Comments
 (0)