mirror of https://github.com/grafana/grafana
Ensure that datasource apiservers receive and forwards headers (#92304)
* Ensure that datasource apiservers receive and forwards headers for datasources: - adds log line for prometheus to see when from alert header is received - add logging to the datasource apiserver - Updates the Connect func in sub query to forward expected headers to datasources and log unexpected ones.pull/92688/head^2
parent
2b3d2e5b40
commit
c0b2fafd5e
@ -0,0 +1,98 @@ |
||||
package datasource |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"net/http" |
||||
"net/http/httptest" |
||||
"testing" |
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend" |
||||
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1" |
||||
"github.com/grafana/grafana/pkg/infra/log" |
||||
"github.com/stretchr/testify/require" |
||||
"k8s.io/apimachinery/pkg/runtime" |
||||
) |
||||
|
||||
func TestSubQueryConnect(t *testing.T) { |
||||
sqr := subQueryREST{ |
||||
builder: &DataSourceAPIBuilder{ |
||||
client: mockClient{ |
||||
lastCalledWithHeaders: &map[string]string{}, |
||||
}, |
||||
datasources: mockDatasources{}, |
||||
contextProvider: mockContextProvider{}, |
||||
log: log.NewNopLogger(), |
||||
}, |
||||
} |
||||
|
||||
mr := mockResponder{} |
||||
handler, err := sqr.Connect(context.Background(), "dsname", nil, mr) |
||||
require.NoError(t, err) |
||||
|
||||
rr := httptest.NewRecorder() |
||||
req := httptest.NewRequest(http.MethodGet, "/some-path", nil) |
||||
req.Header.Set("fromAlert", "true") |
||||
req.Header.Set("Content-Type", "application/json") |
||||
handler.ServeHTTP(rr, req) |
||||
|
||||
// test that headers are forwarded and cased appropriately
|
||||
require.Equal(t, map[string]string{ |
||||
"FromAlert": "true", |
||||
"Content-Type": "application/json", |
||||
}, *sqr.builder.client.(mockClient).lastCalledWithHeaders) |
||||
} |
||||
|
||||
type mockClient struct { |
||||
lastCalledWithHeaders *map[string]string |
||||
} |
||||
|
||||
func (m mockClient) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { |
||||
*m.lastCalledWithHeaders = req.Headers |
||||
return nil, fmt.Errorf("mock error") |
||||
} |
||||
|
||||
func (m mockClient) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { |
||||
return nil |
||||
} |
||||
|
||||
func (m mockClient) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { |
||||
return nil, nil |
||||
} |
||||
|
||||
type mockResponder struct { |
||||
} |
||||
|
||||
// Object writes the provided object to the response. Invoking this method multiple times is undefined.
|
||||
func (m mockResponder) Object(statusCode int, obj runtime.Object) { |
||||
} |
||||
|
||||
// Error writes the provided error to the response. This method may only be invoked once.
|
||||
func (m mockResponder) Error(err error) { |
||||
} |
||||
|
||||
type mockDatasources struct { |
||||
} |
||||
|
||||
// Get gets a specific datasource (that the user in context can see)
|
||||
func (m mockDatasources) Get(ctx context.Context, uid string) (*v0alpha1.DataSourceConnection, error) { |
||||
return nil, nil |
||||
} |
||||
|
||||
// List lists all data sources the user in context can see
|
||||
func (m mockDatasources) List(ctx context.Context) (*v0alpha1.DataSourceConnectionList, error) { |
||||
return nil, nil |
||||
} |
||||
|
||||
// Return settings (decrypted!) for a specific plugin
|
||||
// This will require "query" permission for the user in context
|
||||
func (m mockDatasources) GetInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error) { |
||||
return nil, nil |
||||
} |
||||
|
||||
type mockContextProvider struct { |
||||
} |
||||
|
||||
func (m mockContextProvider) PluginContextForDataSource(ctx context.Context, datasourceSettings *backend.DataSourceInstanceSettings) (backend.PluginContext, error) { |
||||
return backend.PluginContext{}, nil |
||||
} |
Loading…
Reference in new issue