From a2f7e208fd9e6b56e11aed3a9bdd20b9c6d626a0 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:54:04 +0200 Subject: [PATCH] Elasticsearchl: In version check, include `/` (#88779) Elasticsearchl: In version check, include / --- pkg/tsdb/elasticsearch/elasticsearch.go | 17 ++++++++++++----- pkg/tsdb/elasticsearch/elasticsearch_test.go | 6 +++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pkg/tsdb/elasticsearch/elasticsearch.go b/pkg/tsdb/elasticsearch/elasticsearch.go index 69c7fc30a62..354b508463c 100644 --- a/pkg/tsdb/elasticsearch/elasticsearch.go +++ b/pkg/tsdb/elasticsearch/elasticsearch.go @@ -218,9 +218,9 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq logger.Error("Failed to create request url", "error", err, "url", ds.URL, "path", req.Path) } - request, err := http.NewRequestWithContext(ctx, req.Method, esUrl.String(), bytes.NewBuffer(req.Body)) + request, err := http.NewRequestWithContext(ctx, req.Method, esUrl, bytes.NewBuffer(req.Body)) if err != nil { - logger.Error("Failed to create request", "error", err, "url", esUrl.String()) + logger.Error("Failed to create request", "error", err, "url", esUrl) return err } @@ -272,12 +272,19 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq }) } -func createElasticsearchURL(req *backend.CallResourceRequest, ds *es.DatasourceInfo) (*url.URL, error) { +func createElasticsearchURL(req *backend.CallResourceRequest, ds *es.DatasourceInfo) (string, 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) + return "", 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 + esUrlString := esUrl.String() + // If the request path is empty and the URL does not end with a slash, add a slash to the URL. + // This ensures that for version checks executed to the root URL, the URL ends with a slash. + // This is helpful, for example, for load balancers that expect URLs to match the pattern /.*. + if req.Path == "" && esUrlString[len(esUrlString)-1:] != "/" { + return esUrl.String() + "/", nil + } + return esUrlString, nil } diff --git a/pkg/tsdb/elasticsearch/elasticsearch_test.go b/pkg/tsdb/elasticsearch/elasticsearch_test.go index 798e54bf6d0..93a50bf69e8 100644 --- a/pkg/tsdb/elasticsearch/elasticsearch_test.go +++ b/pkg/tsdb/elasticsearch/elasticsearch_test.go @@ -211,13 +211,17 @@ func TestCreateElasticsearchURL(t *testing.T) { {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"}, + {name: "with \"\" path and valid url and /", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://localhost:9200/"}, + {name: "with \"\" path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://localhost:9200/"}, + {name: "with \"\" path and valid url with path", settings: es.DatasourceInfo{URL: "http://elastic:9200/lb"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://elastic:9200/lb/"}, + {name: "with \"\" path and valid url with path and /", settings: es.DatasourceInfo{URL: "http://elastic:9200/lb/"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://elastic:9200/lb/"}, } 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()) + require.Equal(t, test.expected, url) }) } }