-
Notifications
You must be signed in to change notification settings - Fork 638
Description
I am still feeling like it's too hard to do what I feel are common things with this client.
In order to use tokens, you have to implement a custom RoundTripper which is pretty deep and awkward within Go, especialy if you're a developer who just wants to "use elasticsearch" and move on; implementing a custom RoundTripper or custom Transport is tedious.
In order to use custom ssl certs, you have to modify the TLSClientConfig of the transport. This is still pretty deep within net/http as compared to the abstraction layer "elasticsearch client library" ; deeper than I'd prefer.
I was unable to find any solid examples of setting both custom headers (for tokens) and setting custom CA certs.
To that end, here's what I found works; this code requires Go 1.13 for http.Transport.Clone()
package main
import (
"crypto/x509"
"fmt"
"github.com/elastic/go-elasticsearch/v8"
"io/ioutil"
"log"
"net/http"
"os"
)
type CustomRoundTripper struct {
http.RoundTripper
Custom func(*http.Request) (*http.Response, error)
}
func (crt CustomRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
return crt.Custom(req)
}
func main() {
esurl := os.Args[1]
token := os.Args[2]
cafile := os.Args[3]
transport := http.DefaultTransport.(*http.Transport).Clone()
var err error
transport.TLSClientConfig.RootCAs, err = x509.SystemCertPool()
b, err := ioutil.ReadFile(cafile)
if err != nil {
log.Printf("Error reading additional ca certs in path %s / error %s", cafile, err)
os.Exit(1)
}
ok := transport.TLSClientConfig.RootCAs.AppendCertsFromPEM(b)
if !ok {
log.Printf("No certs were found in the additional ca cert path: %s", cafile)
os.Exit(1)
}
crt := CustomRoundTripper{
Custom: func(req *http.Request) (*http.Response, error) {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
return transport.RoundTrip(req)
},
}
config := elasticsearch.Config{
Addresses: []string{esurl},
Transport: crt,
}
es, err := elasticsearch.NewClient(config)
if err != nil {
log.Printf("Error creating ES client: %s", err)
os.Exit(1)
}
resp, err := es.Ping()
if err != nil {
fmt.Printf("Error pinging ES: %s\n", err)
os.Exit(1)
}
fmt.Printf("Response: %s\n", resp)
}
Could we provide some kind of helper function in this library to help users generate their custom Transport? Something like:
elasticsearch.NewClient(elasticsearch.Config{
Transport: happyHttpHelper{
Headers: { ... },
AdditionalCARoots: ...
}
})
Especially as tokens are becoming more prominent in Elasticsearch (API tokens, etc), it would improve things if we made it less code to achieve this; especially if that "less code" removes areas of Go that, I assume, people do not commonly travel (DIY Transport implementations, etc)