diff --git a/pkg/tests/api/elasticsearch/elasticsearch_test.go b/pkg/tests/api/elasticsearch/elasticsearch_test.go new file mode 100644 index 00000000000..5dc7ffae8b4 --- /dev/null +++ b/pkg/tests/api/elasticsearch/elasticsearch_test.go @@ -0,0 +1,117 @@ +package elasticsearch + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "testing" + + "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/org" + "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/user" + "github.com/grafana/grafana/pkg/tests/testinfra" + "github.com/stretchr/testify/require" +) + +func TestIntegrationElasticsearch(t *testing.T) { + dir, path := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{ + DisableAnonymous: true, + }) + + grafanaListeningAddr, testEnv := testinfra.StartGrafanaEnv(t, dir, path) + ctx := context.Background() + + createUser(t, testEnv.SQLStore, user.CreateUserCommand{ + DefaultOrgRole: string(org.RoleAdmin), + Password: "admin", + Login: "admin", + }) + + var outgoingRequest *http.Request + outgoingServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + outgoingRequest = r + w.WriteHeader(http.StatusUnauthorized) + })) + t.Cleanup(outgoingServer.Close) + + jsonData := simplejson.NewFromAny(map[string]interface{}{ + "httpMethod": "post", + "httpHeaderName1": "X-CUSTOM-HEADER", + "esVersion": "8.0.0", + "timeField": "@timestamp", + }) + secureJSONData := map[string]string{ + "basicAuthPassword": "basicAuthPassword", + "httpHeaderValue1": "custom-header-value", + } + + uid := "es" + err := testEnv.Server.HTTPServer.DataSourcesService.AddDataSource(ctx, &datasources.AddDataSourceCommand{ + OrgId: 1, + Access: datasources.DS_ACCESS_PROXY, + Name: "Elasticsearch", + Type: datasources.DS_ES, + Uid: uid, + Url: outgoingServer.URL, + BasicAuth: true, + BasicAuthUser: "basicAuthUser", + JsonData: jsonData, + SecureJsonData: secureJSONData, + }) + require.NoError(t, err) + + t.Run("When calling /api/ds/query should set expected headers on outgoing HTTP request", func(t *testing.T) { + query := simplejson.NewFromAny(map[string]interface{}{ + "datasource": map[string]interface{}{ + "uid": uid, + }, + "rawQuery": "*", + "type": "", + "timeField": "@timestamp", + }) + 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) + // nolint:gosec + resp, err := http.Post(u, "application/json", buf1) + require.NoError(t, err) + + require.Equal(t, http.StatusInternalServerError, 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, "custom-header-value", outgoingRequest.Header.Get("X-CUSTOM-HEADER")) + username, pwd, ok := outgoingRequest.BasicAuth() + require.True(t, ok) + require.Equal(t, "basicAuthUser", username) + require.Equal(t, "basicAuthPassword", pwd) + }) +} + +func createUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserCommand) int64 { + t.Helper() + + store.Cfg.AutoAssignOrg = true + store.Cfg.AutoAssignOrgId = 1 + + u, err := store.CreateUser(context.Background(), cmd) + require.NoError(t, err) + return u.ID +}