Loki: Add dashboard and panel names as headers (#92096)

* feat(nameHeaders): add feature flag

* add safe parsing of headers

* use headers in loki datasource

* Loki: add option to pass headers to Loki

* Loki: add datasource tests for dashboard names

* cleanup

* DataSourceWithBackend: add test

* rename to `sanitizeHeader`

* Loki: add condition when to add headers

* Loki: add e2e tests

* Loki: change test name
This commit is contained in:
Sven Grossmann
2024-08-22 21:30:43 +02:00
committed by GitHub
parent a7b57be04f
commit ec857e1de9
15 changed files with 307 additions and 7 deletions
+86 -1
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/tests/testinfra"
@@ -30,7 +31,8 @@ func TestIntegrationLoki(t *testing.T) {
t.Skip("skipping integration test")
}
dir, path := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
DisableAnonymous: true,
DisableAnonymous: true,
EnableFeatureToggles: []string{featuremgmt.FlagLokiSendDashboardPanelNames},
})
grafanaListeningAddr, testEnv := testinfra.StartGrafanaEnv(t, dir, path)
@@ -106,4 +108,87 @@ func TestIntegrationLoki(t *testing.T) {
require.Equal(t, "basicAuthUser", username)
require.Equal(t, "basicAuthPassword", pwd)
})
t.Run("should forward `X-Dashboard-Title` header but no `X-Panel-Title`", func(t *testing.T) {
query := simplejson.NewFromAny(map[string]interface{}{
"datasource": map[string]interface{}{
"uid": uid,
},
"expr": "{job=\"grafana\"}",
})
buf1 := &bytes.Buffer{}
err = json.NewEncoder(buf1).Encode(dtos.MetricRequest{
From: "now-1h",
To: "now",
Queries: []*simplejson.Json{query},
})
require.NoError(t, err)
u := fmt.Sprintf("http://admin:admin@%s/api/ds/query", grafanaListeningAddr)
req, err := http.NewRequest("POST", u, buf1)
if err != nil {
require.NoError(t, err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Dashboard-Title", "My Dashboard Title")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
t.Cleanup(func() {
err := resp.Body.Close()
require.NoError(t, err)
})
_, err = io.ReadAll(resp.Body)
require.NoError(t, err)
require.NotNil(t, outgoingRequest)
require.Equal(t, "My Dashboard Title", outgoingRequest.Header.Get("X-Dashboard-Title"))
require.Equal(t, "", outgoingRequest.Header.Get("X-Panel-Title"))
username, pwd, ok := outgoingRequest.BasicAuth()
require.True(t, ok)
require.Equal(t, "basicAuthUser", username)
require.Equal(t, "basicAuthPassword", pwd)
})
t.Run("should forward `X-Dashboard-Title` and `X-Panel-Title` header", func(t *testing.T) {
query := simplejson.NewFromAny(map[string]interface{}{
"datasource": map[string]interface{}{
"uid": uid,
},
"expr": "{job=\"grafana\"}",
})
buf1 := &bytes.Buffer{}
err = json.NewEncoder(buf1).Encode(dtos.MetricRequest{
From: "now-1h",
To: "now",
Queries: []*simplejson.Json{query},
})
require.NoError(t, err)
u := fmt.Sprintf("http://admin:admin@%s/api/ds/query", grafanaListeningAddr)
req, err := http.NewRequest("POST", u, buf1)
if err != nil {
require.NoError(t, err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Dashboard-Title", "My Dashboard Title")
req.Header.Set("X-Panel-Title", "My Panel Title")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
t.Cleanup(func() {
err := resp.Body.Close()
require.NoError(t, err)
})
_, err = io.ReadAll(resp.Body)
require.NoError(t, err)
require.NotNil(t, outgoingRequest)
require.Equal(t, "My Dashboard Title", outgoingRequest.Header.Get("X-Dashboard-Title"))
require.Equal(t, "My Panel Title", outgoingRequest.Header.Get("X-Panel-Title"))
username, pwd, ok := outgoingRequest.BasicAuth()
require.True(t, ok)
require.Equal(t, "basicAuthUser", username)
require.Equal(t, "basicAuthPassword", pwd)
})
}