Elasticsearch: Fix resource calls for paths that include : (#82327)
* Elasticsearch: Fix resource calls for paths that include : * Add tests * Add test case and comment * Remove redundant comment
This commit is contained in:
@@ -205,21 +205,11 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq
|
||||
return err
|
||||
}
|
||||
|
||||
esUrl, err := url.Parse(ds.URL)
|
||||
esUrl, err := createElasticsearchURL(req, ds)
|
||||
if err != nil {
|
||||
logger.Error("Failed to parse data source URL", "error", err, "url", ds.URL)
|
||||
return err
|
||||
logger.Error("Failed to create request url", "error", err, "url", ds.URL, "path", req.Path)
|
||||
}
|
||||
|
||||
resourcePath, err := url.Parse(req.Path)
|
||||
if err != nil {
|
||||
logger.Error("Failed to parse data source path", "error", err, "url", req.Path)
|
||||
return err
|
||||
}
|
||||
|
||||
// We take the path and the query-string only
|
||||
esUrl.RawQuery = resourcePath.RawQuery
|
||||
esUrl.Path = path.Join(esUrl.Path, resourcePath.Path)
|
||||
request, err := http.NewRequestWithContext(ctx, req.Method, esUrl.String(), bytes.NewBuffer(req.Body))
|
||||
if err != nil {
|
||||
logger.Error("Failed to create request", "error", err, "url", esUrl.String())
|
||||
@@ -269,3 +259,13 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq
|
||||
Body: body,
|
||||
})
|
||||
}
|
||||
|
||||
func createElasticsearchURL(req *backend.CallResourceRequest, ds *es.DatasourceInfo) (*url.URL, error) {
|
||||
esUrl, err := url.Parse(ds.URL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse data source URL: %s, error: %w", ds.URL, err)
|
||||
}
|
||||
|
||||
esUrl.Path = path.Join(esUrl.Path, req.Path)
|
||||
return esUrl, nil
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
es "github.com/grafana/grafana/pkg/tsdb/elasticsearch/client"
|
||||
)
|
||||
|
||||
type datasourceInfo struct {
|
||||
@@ -71,3 +72,32 @@ func TestNewInstanceSettings(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestCreateElasticsearchURL(t *testing.T) {
|
||||
tt := []struct {
|
||||
name string
|
||||
settings es.DatasourceInfo
|
||||
req backend.CallResourceRequest
|
||||
expected string
|
||||
}{
|
||||
{name: "with /_msearch path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "_msearch"}, expected: "http://localhost:9200/_msearch"},
|
||||
{name: "with _msearch path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "_msearch"}, expected: "http://localhost:9200/_msearch"},
|
||||
{name: "with _msearch path and valid url with /", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "_msearch"}, expected: "http://localhost:9200/_msearch"},
|
||||
{name: "with _mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "/_mapping"}, expected: "http://localhost:9200/_mapping"},
|
||||
{name: "with /_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "/_mapping"}, expected: "http://localhost:9200/_mapping"},
|
||||
{name: "with /_mapping path and valid url with /", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "/_mapping"}, expected: "http://localhost:9200/_mapping"},
|
||||
{name: "with abc/_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "abc/_mapping"}, expected: "http://localhost:9200/abc/_mapping"},
|
||||
{name: "with /abc/_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "abc/_mapping"}, expected: "http://localhost:9200/abc/_mapping"},
|
||||
{name: "with /abc/_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "abc/_mapping"}, expected: "http://localhost:9200/abc/_mapping"},
|
||||
// This is to support mappings to cross cluster search that includes ":"
|
||||
{name: "with path including :", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "ab:c/_mapping"}, expected: "http://localhost:9200/ab:c/_mapping"},
|
||||
}
|
||||
|
||||
for _, test := range tt {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
url, err := createElasticsearchURL(&test.req, &test.settings)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.expected, url.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user