Alerting: Add custom headers support for recording rules custom datasource writer (#105618)

Alerting: Add custom headers support for recording rules datasource writer
This commit is contained in:
Alexander Akhmetov
2025-05-19 19:42:22 +02:00
committed by GitHub
parent 1c99ace68d
commit 04f7f2451d
4 changed files with 40 additions and 0 deletions
+1
View File
@@ -656,6 +656,7 @@ func createRecordingWriter(featureToggles featuremgmt.FeatureToggles, settings s
if featureToggles.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRulesDatasources) {
cfg := writer.DatasourceWriterConfig{
Timeout: settings.Timeout,
CustomHeaders: settings.CustomHeaders,
DefaultDatasourceUID: settings.DefaultDatasourceUID,
}
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"path"
"strings"
@@ -37,6 +38,10 @@ type DatasourceWriterConfig struct {
// This exists to cater for upgrading from old versions of Grafana, where rule
// definitions may not have a target data source specified.
DefaultDatasourceUID string
// CustomHeaders is a map of optional custom HTTP headers
// to include in recording rule write requests.
CustomHeaders map[string]string
}
type DatasourceWriter struct {
@@ -172,12 +177,18 @@ func (w *DatasourceWriter) makeWriter(ctx context.Context, orgID int64, dsUID st
return nil, err
}
headers := make(http.Header)
for k, v := range w.cfg.CustomHeaders {
headers.Add(k, v)
}
cfg := PrometheusWriterConfig{
URL: u.String(),
HTTPOptions: httpclient.Options{
Timeouts: ho.Timeouts,
TLS: ho.TLS,
BasicAuth: ho.BasicAuth,
Header: headers,
},
Timeout: w.cfg.Timeout,
}
@@ -120,6 +120,30 @@ func TestDatasourceWriter(t *testing.T) {
err := writer.WriteDatasource(context.Background(), "", "metric", time.Now(), frames, 1, map[string]string{})
require.NoError(t, err)
})
t.Run("when custom headers are configured, they are passed to the request", func(t *testing.T) {
datasources.Reset()
header1 := "X-Custom-Header"
header2 := "X-Another-Header"
headers := map[string]string{
header1: "test-value",
header2: "another-value",
}
cfg = DatasourceWriterConfig{
Timeout: time.Second * 5,
DefaultDatasourceUID: "prom-2",
CustomHeaders: headers,
}
writer = NewDatasourceWriter(cfg, datasources, httpclient.NewProvider(), clock.New(), log.New("test"), met)
err := writer.WriteDatasource(context.Background(), "prom-1", "metric", time.Now(), frames, 1, map[string]string{})
require.NoError(t, err)
assert.Equal(t, headers[header1], datasources.prom1.LastHeaders.Get(header1))
assert.Equal(t, headers[header2], datasources.prom1.LastHeaders.Get(header2))
})
}
func TestDatasourceWriterGetRemoteWriteURL(t *testing.T) {
+4
View File
@@ -20,6 +20,7 @@ type TestRemoteWriteTarget struct {
mtx sync.Mutex
RequestsCount int
LastRequestBody string
LastHeaders http.Header
ExpectedPath string
}
@@ -30,6 +31,7 @@ func NewTestRemoteWriteTarget(t *testing.T) *TestRemoteWriteTarget {
target := &TestRemoteWriteTarget{
RequestsCount: 0,
LastRequestBody: "",
LastHeaders: http.Header{},
ExpectedPath: RemoteWriteEndpoint,
}
@@ -41,6 +43,7 @@ func NewTestRemoteWriteTarget(t *testing.T) *TestRemoteWriteTarget {
target.mtx.Lock()
defer target.mtx.Unlock()
target.RequestsCount += 1
target.LastHeaders = r.Header.Clone()
bd, err := io.ReadAll(r.Body)
defer func() {
_ = r.Body.Close()
@@ -81,4 +84,5 @@ func (s *TestRemoteWriteTarget) Reset() {
defer s.mtx.Unlock()
s.RequestsCount = 0
s.LastRequestBody = ""
s.LastHeaders = http.Header{}
}