diff --git a/docker-compose.yaml b/docker-compose.yaml index 03688ab2..ec84914e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,7 +12,6 @@ services: - ./provisioning/dashboards-actual/:/dashboards/ - ./provisioning:/etc/grafana/provisioning - ./dist:/var/lib/grafana/plugins/yesoreyeram-infinity-datasource - - grafana-png:/var/lib/grafana/png environment: - TERM=linux - GF_DEFAULT_APP_MODE=development @@ -23,6 +22,3 @@ services: - GF_SECURITY_ANGULAR_SUPPORT_ENABLED=false - GF_SECURITY_CSRF_ALWAYS_CHECK=true - GF_ENTERPRISE_LICENSE_TEXT=$GF_ENTERPRISE_LICENSE_TEXT - -volumes: - grafana-png: diff --git a/pkg/infinity/client.go b/pkg/infinity/client.go index 5b1af33d..5d6c6dc7 100644 --- a/pkg/infinity/client.go +++ b/pkg/infinity/client.go @@ -192,11 +192,11 @@ func replaceSect(input string, settings models.InfinitySettings, includeSect boo return input } -func (client *Client) req(ctx context.Context, url string, body io.Reader, settings models.InfinitySettings, query models.Query, requestHeaders map[string]string, pCtx *backend.PluginContext) (obj any, statusCode int, duration time.Duration, err error) { +func (client *Client) req(ctx context.Context, pCtx *backend.PluginContext, url string, body io.Reader, settings models.InfinitySettings, query models.Query, requestHeaders map[string]string) (obj any, statusCode int, duration time.Duration, err error) { ctx, span := tracing.DefaultTracer().Start(ctx, "client.req") logger := backend.Logger.FromContext(ctx) defer span.End() - req, err := GetRequest(ctx, settings, body, query, requestHeaders, true, pCtx) + req, err := GetRequest(ctx, pCtx, settings, body, query, requestHeaders, true) if err != nil { return nil, http.StatusInternalServerError, 0, errorsource.DownstreamError(fmt.Errorf("error preparing request. %w", err), false) } @@ -263,7 +263,7 @@ func removeBOMContent(input []byte) []byte { return bytes.TrimPrefix(input, []byte("\xef\xbb\xbf")) } -func (client *Client) GetResults(ctx context.Context, query models.Query, requestHeaders map[string]string, pCtx *backend.PluginContext) (o any, statusCode int, duration time.Duration, err error) { +func (client *Client) GetResults(ctx context.Context, pCtx *backend.PluginContext, query models.Query, requestHeaders map[string]string) (o any, statusCode int, duration time.Duration, err error) { logger := backend.Logger.FromContext(ctx) if query.Source == "azure-blob" { if strings.TrimSpace(query.AzBlobContainerName) == "" || strings.TrimSpace(query.AzBlobName) == "" { @@ -296,9 +296,9 @@ func (client *Client) GetResults(ctx context.Context, query models.Query, reques switch strings.ToUpper(query.URLOptions.Method) { case http.MethodPost: body := GetQueryBody(ctx, query) - return client.req(ctx, query.URL, body, client.Settings, query, requestHeaders, pCtx) + return client.req(ctx, pCtx, query.URL, body, client.Settings, query, requestHeaders) default: - return client.req(ctx, query.URL, nil, client.Settings, query, requestHeaders, pCtx) + return client.req(ctx, pCtx, query.URL, nil, client.Settings, query, requestHeaders) } } diff --git a/pkg/infinity/client_test.go b/pkg/infinity/client_test.go index 6f4e830d..775af03f 100644 --- a/pkg/infinity/client_test.go +++ b/pkg/infinity/client_test.go @@ -69,7 +69,7 @@ func TestInfinityClient_GetResults(t *testing.T) { HttpClient: &http.Client{}, } pluginContext := &backend.PluginContext{} - gotO, statusCode, duration, err := client.GetResults(context.Background(), tt.query, tt.requestHeaders, pluginContext) + gotO, statusCode, duration, err := client.GetResults(context.Background(), pluginContext, tt.query, tt.requestHeaders) if (err != nil) != tt.wantErr { t.Errorf("GetResults() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/pkg/infinity/headers.go b/pkg/infinity/headers.go index 766394f5..de5a1416 100644 --- a/pkg/infinity/headers.go +++ b/pkg/infinity/headers.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/grafana/grafana-infinity-datasource/pkg/models" + "github.com/grafana/grafana-plugin-sdk-go/backend" ) const dummyHeader = "xxxxxxxx" @@ -65,18 +66,31 @@ func ApplyContentTypeHeader(query models.Query, settings models.InfinitySettings return req } -func ApplyHeadersFromSettings(settings models.InfinitySettings, req *http.Request, includeSect bool) *http.Request { +func ApplyHeadersFromSettings(pCtx *backend.PluginContext, requestHeaders map[string]string, settings models.InfinitySettings, req *http.Request, includeSect bool) *http.Request { for key, value := range settings.CustomHeaders { - val := dummyHeader + headerValue := dummyHeader if includeSect { - val = value + headerValue = value } - if key != "" { - req.Header.Add(key, val) - if strings.EqualFold(key, headerKeyAccept) || strings.EqualFold(key, headerKeyContentType) { - req.Header.Set(key, val) + if pCtx != nil { + headerValue = strings.ReplaceAll(headerValue, "${__org.id}", fmt.Sprintf("%d", pCtx.OrgID)) + headerValue = strings.ReplaceAll(headerValue, "${__plugin.id}", pCtx.PluginID) + headerValue = strings.ReplaceAll(headerValue, "${__plugin.version}", pCtx.PluginVersion) + if pCtx.DataSourceInstanceSettings != nil { + headerValue = strings.ReplaceAll(headerValue, "${__ds.uid}", pCtx.DataSourceInstanceSettings.UID) + headerValue = strings.ReplaceAll(headerValue, "${__ds.name}", pCtx.DataSourceInstanceSettings.Name) + headerValue = strings.ReplaceAll(headerValue, "${__ds.id}", fmt.Sprintf("%d", pCtx.DataSourceInstanceSettings.ID)) + } + if pCtx.User != nil { + headerValue = strings.ReplaceAll(headerValue, "${__user.login}", pCtx.User.Login) + headerValue = strings.ReplaceAll(headerValue, "${__user.email}", pCtx.User.Email) + headerValue = strings.ReplaceAll(headerValue, "${__user.name}", pCtx.User.Name) + // headerValue = strings.ReplaceAll(headerValue, "${__user.role}", pCtx.User.Role) } } + if key != "" { + req.Header.Set(key, headerValue) + } } return req } @@ -156,4 +170,4 @@ func getQueryReqHeader(requestHeaders map[string]string, headerName string) stri } return "" -} \ No newline at end of file +} diff --git a/pkg/infinity/headers_test.go b/pkg/infinity/headers_test.go index 89d6b7bc..61ec96ca 100644 --- a/pkg/infinity/headers_test.go +++ b/pkg/infinity/headers_test.go @@ -1,8 +1,13 @@ package infinity import ( + "net/http" "strings" "testing" + + "github.com/grafana/grafana-infinity-datasource/pkg/models" + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/stretchr/testify/require" ) func TestGetQueryReqHeader(t *testing.T) { @@ -62,4 +67,74 @@ func TestGetQueryReqHeader(t *testing.T) { } }) } -} \ No newline at end of file +} + +func TestApplyGrafanaHeaders(t *testing.T) { + tests := []struct { + name string + settings models.InfinitySettings + pCtx *backend.PluginContext + want map[string]string + }{ + { + name: "should interpolate grafana headers correctly when set in settings", + settings: models.InfinitySettings{ + CustomHeaders: map[string]string{ + "X-Grafana-User": "${__user.login}", + "X-Grafana-UserID": "${__user.login}", + "X-Grafana-UserEmail": "${__user.email}", + "X-Grafana-UserName": "${__user.name}", + "X-Grafana-UserRole": "${__user.role}", + "X-Grafana-OrgID": "${__org.id}", + "X-Grafana-PluginID": "${__plugin.id}", + "X-Grafana-PluginVersion": "${__plugin.version}", + "X-Grafana-DatasourceUID": "${__ds.uid}", + "X-Grafana-DatasourceName": "${__ds.name}", + "X-Grafana-DatasourceID": "${__ds.id}", + "X-Misc-Value": "${__user.login}@${__plugin.id}", + }, + }, + pCtx: &backend.PluginContext{ + OrgID: 12345, + PluginID: "my-plugin-id", + PluginVersion: "0.0.0-preview.1", + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + ID: 123, + UID: "my-ds-uid", + Name: "my-ds-name", + }, + User: &backend.User{ + Email: "testuser@localhost", + Login: "testuser", + Name: "Test User", + Role: "Admin", + }, + }, + want: map[string]string{ + "X-Grafana-User": "testuser", + "X-Grafana-UserID": "testuser", + "X-Grafana-UserEmail": "testuser@localhost", + "X-Grafana-UserName": "Test User", + "X-Grafana-UserRole": "${__user.role}", + "X-Grafana-OrgID": "12345", + "X-Grafana-PluginID": "my-plugin-id", + "X-Grafana-PluginVersion": "0.0.0-preview.1", + "X-Grafana-DatasourceUID": "my-ds-uid", + "X-Grafana-DatasourceName": "my-ds-name", + "X-Grafana-DatasourceID": "123", + "X-Misc-Value": "testuser@my-plugin-id", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req, _ := http.NewRequest("GET", "http://example.com", nil) + got := ApplyHeadersFromSettings(tt.pCtx, map[string]string{}, tt.settings, req, true) + require.Equal(t, len(tt.want), len(got.Header)) + for k, v := range tt.want { + require.Equal(t, v, got.Header.Get(k)) + } + }) + } +} diff --git a/pkg/infinity/remote.go b/pkg/infinity/remote.go index 256f264f..c15a26fe 100644 --- a/pkg/infinity/remote.go +++ b/pkg/infinity/remote.go @@ -16,17 +16,17 @@ import ( "github.com/grafana/infinity-libs/lib/go/transformations" ) -func GetFrameForURLSources(ctx context.Context, query models.Query, infClient Client, requestHeaders map[string]string, pCtx *backend.PluginContext) (*data.Frame, error) { +func GetFrameForURLSources(ctx context.Context, pCtx *backend.PluginContext, query models.Query, infClient Client, requestHeaders map[string]string) (*data.Frame, error) { ctx, span := tracing.DefaultTracer().Start(ctx, "GetFrameForURLSources") defer span.End() if query.Type == models.QueryTypeJSON && query.Parser == models.InfinityParserBackend && query.PageMode != models.PaginationModeNone && query.PageMode != "" { - return GetPaginatedResults(ctx, query, infClient, requestHeaders, pCtx) + return GetPaginatedResults(ctx, pCtx, query, infClient, requestHeaders) } - frame, _, err := GetFrameForURLSourcesWithPostProcessing(ctx, query, infClient, requestHeaders, true, pCtx) + frame, _, err := GetFrameForURLSourcesWithPostProcessing(ctx, pCtx, query, infClient, requestHeaders, true) return frame, err } -func GetPaginatedResults(ctx context.Context, query models.Query, infClient Client, requestHeaders map[string]string, pCtx *backend.PluginContext) (*data.Frame, error) { +func GetPaginatedResults(ctx context.Context, pCtx *backend.PluginContext, query models.Query, infClient Client, requestHeaders map[string]string) (*data.Frame, error) { ctx, span := tracing.DefaultTracer().Start(ctx, "GetPaginatedResults") defer span.End() frames := []*data.Frame{} @@ -65,12 +65,12 @@ func GetPaginatedResults(ctx context.Context, query models.Query, infClient Clie case models.PaginationModeCursor: queries = append(queries, query) default: - frame, _, err := GetFrameForURLSourcesWithPostProcessing(ctx, query, infClient, requestHeaders, true, pCtx) + frame, _, err := GetFrameForURLSourcesWithPostProcessing(ctx, pCtx, query, infClient, requestHeaders, true) return frame, err } if query.PageMode != models.PaginationModeCursor { for _, currentQuery := range queries { - frame, _, err := GetFrameForURLSourcesWithPostProcessing(ctx, currentQuery, infClient, requestHeaders, false, pCtx) + frame, _, err := GetFrameForURLSourcesWithPostProcessing(ctx, pCtx, currentQuery, infClient, requestHeaders, false) frames = append(frames, frame) errs = errors.Join(errs, err) } @@ -87,7 +87,7 @@ func GetPaginatedResults(ctx context.Context, query models.Query, infClient Clie break } i++ - frame, cursor, err := GetFrameForURLSourcesWithPostProcessing(ctx, currentQuery, infClient, requestHeaders, false, pCtx) + frame, cursor, err := GetFrameForURLSourcesWithPostProcessing(ctx, pCtx, currentQuery, infClient, requestHeaders, false) oCursor = cursor frames = append(frames, frame) errs = errors.Join(errs, err) @@ -135,13 +135,13 @@ func ApplyPaginationItemToQuery(currentQuery models.Query, fieldType models.Pagi return currentQuery } -func GetFrameForURLSourcesWithPostProcessing(ctx context.Context, query models.Query, infClient Client, requestHeaders map[string]string, postProcessingRequired bool, pCtx *backend.PluginContext) (*data.Frame, string, error) { +func GetFrameForURLSourcesWithPostProcessing(ctx context.Context, pCtx *backend.PluginContext, query models.Query, infClient Client, requestHeaders map[string]string, postProcessingRequired bool) (*data.Frame, string, error) { ctx, span := tracing.DefaultTracer().Start(ctx, "GetFrameForURLSourcesWithPostProcessing") logger := backend.Logger.FromContext(ctx) defer span.End() frame := GetDummyFrame(query) cursor := "" - urlResponseObject, statusCode, duration, err := infClient.GetResults(ctx, query, requestHeaders, pCtx) + urlResponseObject, statusCode, duration, err := infClient.GetResults(ctx, pCtx, query, requestHeaders) frame.Meta.ExecutedQueryString = infClient.GetExecutedURL(ctx, query) if infClient.IsMock { duration = 123 diff --git a/pkg/infinity/request.go b/pkg/infinity/request.go index 71ff1057..5d5e5d0c 100644 --- a/pkg/infinity/request.go +++ b/pkg/infinity/request.go @@ -14,7 +14,7 @@ import ( "moul.io/http2curl" ) -func GetRequest(ctx context.Context, settings models.InfinitySettings, body io.Reader, query models.Query, requestHeaders map[string]string, includeSect bool, pCtx *backend.PluginContext) (req *http.Request, err error) { +func GetRequest(ctx context.Context, pCtx *backend.PluginContext, settings models.InfinitySettings, body io.Reader, query models.Query, requestHeaders map[string]string, includeSect bool) (req *http.Request, err error) { ctx, span := tracing.DefaultTracer().Start(ctx, "GetRequest") defer span.End() url, err := GetQueryURL(ctx, settings, query, includeSect) @@ -29,13 +29,12 @@ func GetRequest(ctx context.Context, settings models.InfinitySettings, body io.R } req = ApplyAcceptHeader(query, settings, req, includeSect) req = ApplyContentTypeHeader(query, settings, req, includeSect) - req = ApplyHeadersFromSettings(settings, req, includeSect) req = ApplyHeadersFromQuery(query, settings, req, includeSect) + req = ApplyHeadersFromSettings(pCtx, requestHeaders, settings, req, includeSect) req = ApplyBasicAuth(settings, req, includeSect) req = ApplyBearerToken(settings, req, includeSect) req = ApplyApiKeyAuth(settings, req, includeSect) req = ApplyForwardedOAuthIdentity(requestHeaders, settings, req, includeSect) - req = ApplyGrafanaHeaders(settings, req, pCtx) return req, err } @@ -97,7 +96,7 @@ func NormalizeURL(u string) string { func (client *Client) GetExecutedURL(ctx context.Context, query models.Query) string { out := []string{} if query.Source != "inline" && query.Source != "azure-blob" { - req, err := GetRequest(ctx, client.Settings, GetQueryBody(ctx, query), query, map[string]string{}, false, nil) + req, err := GetRequest(ctx, nil, client.Settings, GetQueryBody(ctx, query), query, map[string]string{}, false) if err != nil { return fmt.Sprintf("error retrieving full url. %s", query.URL) } @@ -125,17 +124,3 @@ func (client *Client) GetExecutedURL(ctx context.Context, query models.Query) st } return strings.Join(out, "\n") } - -// ApplyGrafanaHeaders adds Grafana-specific headers if enabled in settings -func ApplyGrafanaHeaders(settings models.InfinitySettings, req *http.Request, pCtx *backend.PluginContext) *http.Request { - if pCtx == nil { - return req - } - if settings.SendUserHeader && pCtx.User != nil { - req.Header.Set("X-Grafana-User", pCtx.User.Login) - } - if settings.SendDatasourceIDHeader && pCtx.DataSourceInstanceSettings != nil { - req.Header.Set("X-Grafana-Datasource-UID", pCtx.DataSourceInstanceSettings.UID) - } - return req -} diff --git a/pkg/infinity/request_test.go b/pkg/infinity/request_test.go index 504b8c42..6598b6a7 100644 --- a/pkg/infinity/request_test.go +++ b/pkg/infinity/request_test.go @@ -3,6 +3,7 @@ package infinity_test import ( "context" "fmt" + "io" "net/http" "testing" @@ -269,123 +270,50 @@ func TestNormalizeURL(t *testing.T) { } } -func TestApplyGrafanaHeaders(t *testing.T) { +func TestGetRequest(t *testing.T) { tests := []struct { - name string - settings models.InfinitySettings - pCtx *backend.PluginContext - want map[string]string + name string + pCtx *backend.PluginContext + settings models.InfinitySettings + body io.Reader + query models.Query + requestHeaders map[string]string + wantReq http.Request + wantErr error }{ { - name: "should add user header when enabled", - settings: models.InfinitySettings{ - SendUserHeader: true, - }, - pCtx: &backend.PluginContext{ - User: &backend.User{ - Login: "testuser", - }, - }, - want: map[string]string{ - "X-Grafana-User": "testuser", - }, - }, - { - name: "should add datasource id header when enabled", - settings: models.InfinitySettings{ - SendDatasourceIDHeader: true, - }, - pCtx: &backend.PluginContext{ - DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ - UID: "123", - }, - }, - want: map[string]string{ - "X-Grafana-Datasource-UID": "123", - }, - }, - { - name: "should add both headers when both enabled", - settings: models.InfinitySettings{ - SendUserHeader: true, - SendDatasourceIDHeader: true, - }, - pCtx: &backend.PluginContext{ - User: &backend.User{ - Login: "testuser", - }, - DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ - UID: "123", - }, - }, - want: map[string]string{ - "X-Grafana-User": "testuser", - "X-Grafana-Datasource-UID": "123", - }, - }, - { - name: "should not add headers when disabled", - settings: models.InfinitySettings{ - SendUserHeader: false, - SendDatasourceIDHeader: false, - }, - pCtx: &backend.PluginContext{ - User: &backend.User{ - Login: "testuser", - }, - DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ - UID: "123", - }, - }, - want: map[string]string{}, - }, - { - name: "should handle nil plugin context", - settings: models.InfinitySettings{ - SendUserHeader: true, - SendDatasourceIDHeader: true, - }, - pCtx: nil, - want: map[string]string{}, + name: "shouldn't interpolate grafana values from query", + pCtx: &backend.PluginContext{PluginID: "hello"}, + query: models.Query{URLOptions: models.URLOptions{Headers: []models.URLOptionKeyValuePair{{Key: "Something", Value: "${__plugin.id"}}}}, + wantReq: http.Request{Header: http.Header{"Something": []string{"${__plugin.id"}}}, }, { - name: "should handle nil user when user header enabled", - settings: models.InfinitySettings{ - SendUserHeader: true, - }, - pCtx: &backend.PluginContext{ - User: nil, - DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ - UID: "123", - }, - }, - want: map[string]string{}, + name: "should forward grafana headers correctly when set in the custom header settings", + pCtx: &backend.PluginContext{PluginID: "hello"}, + settings: models.InfinitySettings{CustomHeaders: map[string]string{"Something": "${__plugin.id}"}}, + wantReq: http.Request{Header: http.Header{"Something": []string{"hello"}}}, }, { - name: "should handle nil datasource settings when datasource header enabled", - settings: models.InfinitySettings{ - SendDatasourceIDHeader: true, - }, - pCtx: &backend.PluginContext{ - User: &backend.User{Login: "testuser"}, - DataSourceInstanceSettings: nil, - }, - want: map[string]string{}, + name: "should override values from settings compared to query", + pCtx: &backend.PluginContext{PluginID: "hello"}, + query: models.Query{URLOptions: models.URLOptions{Headers: []models.URLOptionKeyValuePair{{Key: "Something", Value: "Some Value"}}}}, + settings: models.InfinitySettings{CustomHeaders: map[string]string{"Something": "${__plugin.id}"}}, + wantReq: http.Request{Header: http.Header{"Something": []string{"hello"}}}, }, } - for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - req, _ := http.NewRequest("GET", "http://example.com", nil) - got := infinity.ApplyGrafanaHeaders(tt.settings, req, tt.pCtx) - - // Verify each expected header - for k, v := range tt.want { - require.Equal(t, v, got.Header.Get(k)) + gotReq, err := infinity.GetRequest(context.TODO(), tt.pCtx, tt.settings, tt.body, tt.query, tt.requestHeaders, true) + if tt.wantErr != nil { + require.NotNil(t, err) + assert.Equal(t, tt.wantErr, err) + return + } + require.NotNil(t, gotReq) + assert.Equal(t, len(tt.wantReq.Header), len(gotReq.Header)) + for k := range tt.wantReq.Header { + require.Equal(t, tt.wantReq.Header.Get(k), gotReq.Header.Get(k)) } - - // Verify no unexpected headers - require.Equal(t, len(tt.want), len(got.Header)) }) } } diff --git a/pkg/models/settings.go b/pkg/models/settings.go index a0dee580..e6ffd04d 100644 --- a/pkg/models/settings.go +++ b/pkg/models/settings.go @@ -117,8 +117,6 @@ type InfinitySettings struct { AzureBlobAccountKey string UnsecuredQueryHandling UnsecuredQueryHandlingMode PathEncodedURLsEnabled bool - SendUserHeader bool - SendDatasourceIDHeader bool // ProxyOpts is used for Secure Socks Proxy configuration ProxyOpts httpclient.Options } @@ -202,8 +200,6 @@ type InfinitySettingsJson struct { AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"` AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"` PathEncodedURLsEnabled bool `json:"pathEncodedUrlsEnabled,omitempty"` - SendUserHeader bool `json:"send_user_header,omitempty"` - SendDatasourceIDHeader bool `json:"send_datasource_id_header,omitempty"` // Security AllowedHosts []string `json:"allowedHosts,omitempty"` UnsecuredQueryHandling UnsecuredQueryHandlingMode `json:"unsecuredQueryHandling,omitempty"` @@ -247,8 +243,6 @@ func LoadSettings(ctx context.Context, config backend.DataSourceInstanceSettings settings.ProxyType = infJson.ProxyType settings.ProxyUrl = infJson.ProxyUrl settings.PathEncodedURLsEnabled = infJson.PathEncodedURLsEnabled - settings.SendUserHeader = infJson.SendUserHeader - settings.SendDatasourceIDHeader = infJson.SendDatasourceIDHeader if settings.ProxyType == "" { settings.ProxyType = ProxyTypeEnv } diff --git a/pkg/pluginhost/handler_checkhealth.go b/pkg/pluginhost/handler_checkhealth.go index ef9cb776..07916d80 100644 --- a/pkg/pluginhost/handler_checkhealth.go +++ b/pkg/pluginhost/handler_checkhealth.go @@ -51,14 +51,14 @@ func CheckHealth(ctx context.Context, client *infinity.Client, req *backend.Chec return checkHealthAzureBlobStorage(ctx, client) } if client.Settings.CustomHealthCheckEnabled && client.Settings.CustomHealthCheckUrl != "" { - _, statusCode, _, err := client.GetResults(ctx, models.Query{ + _, statusCode, _, err := client.GetResults(ctx, &backend.PluginContext{}, models.Query{ Type: models.QueryTypeUQL, Source: "url", URL: client.Settings.CustomHealthCheckUrl, URLOptions: models.URLOptions{ Method: http.MethodGet, }, - }, req.Headers, &backend.PluginContext{}) + }, req.Headers) if err != nil { return &backend.CheckHealthResult{ Status: backend.HealthStatusError, diff --git a/pkg/pluginhost/handler_querydata.go b/pkg/pluginhost/handler_querydata.go index 852abbd4..71604735 100644 --- a/pkg/pluginhost/handler_querydata.go +++ b/pkg/pluginhost/handler_querydata.go @@ -46,12 +46,12 @@ func (ds *DataSource) QueryData(ctx context.Context, req *backend.QueryDataReque response = response1 continue } - response.Responses[q.RefID] = QueryDataQuery(ctx, query, *ds.client, req.Headers, req.PluginContext) + response.Responses[q.RefID] = QueryDataQuery(ctx, req.PluginContext, query, *ds.client, req.Headers) } return response, nil } -func QueryDataQuery(ctx context.Context, query models.Query, infClient infinity.Client, requestHeaders map[string]string, pluginContext backend.PluginContext) (response backend.DataResponse) { +func QueryDataQuery(ctx context.Context, pluginContext backend.PluginContext, query models.Query, infClient infinity.Client, requestHeaders map[string]string) (response backend.DataResponse) { logger := backend.Logger.FromContext(ctx) ctx, span := tracing.DefaultTracer().Start(ctx, "QueryDataQuery", trace.WithAttributes( attribute.String("type", string(query.Type)), @@ -85,7 +85,7 @@ func QueryDataQuery(ctx context.Context, query models.Query, infClient infinity. return errorsource.Response(errorsource.DownstreamError(errors.New("invalid or empty sheet ID"), false)) } query.URL = fmt.Sprintf("https://sheets.googleapis.com/v4/spreadsheets/%s?includeGridData=true&ranges=%s", sheetId, sheetRange) - frame, err := infinity.GetFrameForURLSources(ctx, query, infClient, requestHeaders, &pluginContext) + frame, err := infinity.GetFrameForURLSources(ctx, &pluginContext, query, infClient, requestHeaders) if err != nil { span.RecordError(err) span.SetStatus(500, err.Error()) @@ -119,7 +119,7 @@ func QueryDataQuery(ctx context.Context, query models.Query, infClient infinity. response.ErrorSource = backend.ErrorSourceDownstream return response } - frame, err := infinity.GetFrameForURLSources(ctx, query, infClient, requestHeaders, &pluginContext) + frame, err := infinity.GetFrameForURLSources(ctx, &pluginContext, query, infClient, requestHeaders) if err != nil { logger.Debug("error while performing the infinity query", "msg", err.Error()) if frame != nil { diff --git a/pkg/testsuite/handler_querydata_test.go b/pkg/testsuite/handler_querydata_test.go index 187820bd..fe0aa987 100644 --- a/pkg/testsuite/handler_querydata_test.go +++ b/pkg/testsuite/handler_querydata_test.go @@ -24,7 +24,7 @@ func queryData(t *testing.T, ctx context.Context, backendQuery backend.DataQuery t.Helper() query, err := models.LoadQuery(ctx, backendQuery, pluginContext, infClient.Settings) require.Nil(t, err) - return pluginhost.QueryDataQuery(ctx, query, infClient, requestHeaders, pluginContext) + return pluginhost.QueryDataQuery(ctx, pluginContext, query, infClient, requestHeaders) } func TestAuthentication(t *testing.T) { @@ -938,7 +938,7 @@ func TestRemoteSources(t *testing.T) { client = New("") } - frame, err := infinity.GetFrameForURLSources(context.Background(), query, *client, map[string]string{}, &backend.PluginContext{}) + frame, err := infinity.GetFrameForURLSources(context.Background(), &backend.PluginContext{}, query, *client, map[string]string{}) if tt.wantErr != nil { require.NotNil(t, err) assert.Equal(t, tt.wantErr, err) diff --git a/src/editors/config.editor.tsx b/src/editors/config.editor.tsx index a7040d0c..a223e3a8 100644 --- a/src/editors/config.editor.tsx +++ b/src/editors/config.editor.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import defaultsDeep from 'lodash/defaultsDeep'; import { css } from '@emotion/css'; -import { InlineFormLabel, Input, Button, LinkButton, useTheme2, Collapse as CollapseOriginal, Switch } from '@grafana/ui'; +import { InlineFormLabel, Input, Button, LinkButton, useTheme2, Collapse as CollapseOriginal } from '@grafana/ui'; import { SecureFieldsEditor } from './../components/config/SecureFieldsEditor'; import { AuthEditor } from './config/Auth'; import { ProxyEditor } from './config/ProxyEditor'; @@ -82,38 +82,6 @@ export const HeadersEditor = (props: DataSourcePluginOptionsEditorProps -
- Send User Header - { - onOptionsChange({ - ...options, - jsonData: { - ...options.jsonData, - send_user_header: e.currentTarget.checked, - }, - }); - }} - /> -
When enabled, sends the current Grafana user as X-Grafana-User header
-
-
- Send Datasource ID Header - { - onOptionsChange({ - ...options, - jsonData: { - ...options.jsonData, - send_datasource_id_header: e.currentTarget.checked, - }, - }); - }} - /> -
When enabled, sends the current datasource UID as X-Grafana-Datasource-UID header
-
diff --git a/src/types/config.types.ts b/src/types/config.types.ts index 82e22a47..be39a471 100644 --- a/src/types/config.types.ts +++ b/src/types/config.types.ts @@ -28,6 +28,7 @@ export type AWSAuthProps = { export type InfinityReferenceData = { name: string; data: string }; export type ProxyType = 'none' | 'env' | 'url'; export type UnsecureQueryHandling = 'warn' | 'allow' | 'deny'; +export type HeadersFromGrafana = ''; export interface InfinityOptions extends DataSourceJsonData { auth_method?: AuthType; apiKeyKey?: string; @@ -52,8 +53,6 @@ export interface InfinityOptions extends DataSourceJsonData { unsecuredQueryHandling?: UnsecureQueryHandling; enableSecureSocksProxy?: boolean; pathEncodedUrlsEnabled?: boolean; - send_user_header?: boolean; // Add support for sending X-Grafana-User header - send_datasource_id_header?: boolean; // Add support for sending X-Grafana-Datasource-UID header } export interface InfinitySecureOptions {