opensearch-project / opensearch-go

Go Client for OpenSearch
https://opensearch.org/docs/latest/clients/go/
Apache License 2.0
202 stars 104 forks source link

[BUG] Wrong request path computed in `AliasGetReq` when no indices are specified #617

Open ste93cry opened 1 month ago

ste93cry commented 1 month ago

What is the bug?

OpenSearch supports two kind of routes to get an alias: GET /_alias/alias1 and GET /alias1. To interact with these routes, the opensearchapi package provides the AliasGetReq request. The problem arises when no indices are specified: in this case, the GetRequest() function computes a request path that is equal to //_alias/alias1. When passed to http.NewRequest(), the double slash at the beginning makes _alias be set as host and alias1 as path, and when the host is replaced in setReqURL(), the ending request URL is http://localhost:9200/alias1 instead of the expected http://localhost:9200/_alias/alias1. While the response for the success case is coincidentally compatible, the behavior is different if more than one alias is specified and some do not exist. In that case, the first endpoint returns a structured error while the second returns the information about the existing aliases along with an error message and a status field. This makes it difficult to handle errors as you expect to receive them in a certain format when in reality this is not the case.

curl --location 'localhost:9200/test-index/_alias/alias1,alias2'
{"error":"alias [alias2] missing","status":404,"test-index":{"aliases":{"alias1":{}}}}

curl --location 'localhost:9200/alias1,alias2'
{"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index [alias2]","index":"alias2","resource.id":"alias2","resource.type":"index_or_alias","index_uuid":"_na_"}],"type":"index_not_found_exception","reason":"no such index [alias2]","index":"alias2","resource.id":"alias2","resource.type":"index_or_alias","index_uuid":"_na_"},"status":404}

How can one reproduce the bug?

It it enough to write this code:

if _, err := client.Indices.Alias.Get(context.Background(), opensearchapi.AliasGetReq{Alias: []string{"alias1", "alias2"}}); err != nil {
    var opensearchErr *opensearch.StructError
    if errors.As(err, &opensearchErr) {
        // this works as long as the http://localhost:9200/alias1,alias2 endpoint is called,
        // but the expectation is that localhost:9200/_alias/alias1,alias2 gets called instead,
        // which would return the error in a different format
    }
}

What is the expected behavior?

The request returned by AliasGetReq.GetRequest() should have /_alias/alias1 set as path when no indices are specified.

Do you have any additional context?

It used to work fine before version 3.0. The commit that introduced the bugged code is 9d56cba2f56a4c8d7b8591e011fe4b76e1197194. I'm open to submit a PR to fix the issue once it's triaged.

dblock commented 1 month ago

[Catch All Triage - 1, 2, 3, 4]