ropensci / elastic

R client for the Elasticsearch HTTP API
https://docs.ropensci.org/elastic
Other
245 stars 58 forks source link

Elastic access with API key #283

Closed sebastiz closed 2 years ago

sebastiz commented 3 years ago

Hi can you tell me how I can use your package with an api key.

At the moment Im trying to search with httr using code similar to this:

library(httr) library(RJSONIO) library(curl)

my_query <- rjson::toJSON( '{ "query": { "match" : { "LastName": "MyName" } } }' )

get_scroll_id <- httr::GET( url = "https://MyServer:9200/MyIndex/_search", query = list(scroll = "1m", size = "10000"), encoding = 'json', httr::add_headers( .headers = c( "Authorization" = "ApiKey ****", "Content-Type" = "application/json" ) ), config=httr::config(ssl_verifypeer = FALSE,ssl_verifyhost = FALSE), body = my_query )

scroll_data <- fromJSON(content(get_scroll_id, as="text"))

This returns data but doesn't let me run a query for reasons I dont understand. I wanted to use your packed to connect but Im not sure which parameters to use within the connect function. Thanks in advance

Session Info ```r ```
sckott commented 3 years ago

thanks for your question @sebastiz

fyi: the http client under the hood is https://docs.ropensci.org/crul/ - not httr

see the headers param (as in "request headers")

x <- connect(headers = list(Authorization = 'foobar'))
ping(x)
#> => GET / HTTP/1.1
#> => Host: 127.0.0.1:9200
#> => User-Agent: libcurl/7.64.1 r-curl/4.3.1 crul/1.1.0.93
#> => Accept-Encoding: gzip, deflate
#> => Accept: application/json, text/xml, application/xml, */*
#> => Authorization: foobar
#> =>
#> <= HTTP/1.1 200 OK
#> <= content-type: application/json; charset=UTF-8
#> 
#> .... cutoff

let me know if that works

sebastiz commented 3 years ago

Thanks @sckott. With the example you gave I get the error: Error in curl::curl_fetch_memory(x$url$url, handle = x$url$handle) : schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted. When I run with httr I normally add config=httr::config(ssl_verifypeer = FALSE,ssl_verifyhost = FALSE). How can I add this to the connect parameter in your package? Thanks

sckott commented 3 years ago

crul::set_opts(ssl_verifypeer = FALSE,ssl_verifyhost = FALSE)

sckott commented 3 years ago

you should also be able to pass them into connect - connect(headers = list(Authorization = 'foobar'), ssl_verifypeer = FALSE,ssl_verifyhost = FALSE))

sebastiz commented 3 years ago

Hi @sckott. Sorry to be a pain- Im not very familiar with passing API keys in headers etc.

Just so I can make sure I am doing this correctly I now have:

x <- connect(transport_schema="https",
             headers=c("Authorization" = "ApiKey blablalba=="),
             host="https://MyServer",
             port=9200,
             ssl_verifypeer = FALSE,ssl_verifyhost = FALSE)

but when I enter

docs_get(x, index = 'MyIndex',id=10)

I get the error

Error: 403 - action [cluster:monitor/main] is unauthorized for API key id [HyajjUUU] of user [elastic], this action is granted by the cluster privileges [monitor,manage,all]

The error specifies a different API key to the one I am using in the connect function which makes me think it is ignoring my API. Does that mean I have defined the API key in my connect statement wrongly?

sckott commented 3 years ago

headers should be a named list, so:

x <- connect(transport_schema="https",
             headers = list(Authorization = "ApiKey blablalba=="),
             host="https://MyServer",
             port=9200,
             ssl_verifypeer = FALSE,ssl_verifyhost = FALSE)

host should be just the base domain without the schema, e.g., MyServer.com

After you run your connect() call and before doing a request to the elasticsearch instance (e.g., docs_get) run crul::set_verbose() and then when you run queries against your instance you'll get to see curl request and response headers - You should then see headers like this comment above - you should see a request header like Authorization: your-api-key - If you don't see it then we can diagnose from there

sebastiz commented 3 years ago

Hi @sckott

x <- connect(transport_schema="https",
             headers = list(Authorization = "ApiKey blablalba=="),
             host="https://MyServer",
             port=9200,
             ssl_verifypeer = FALSE,ssl_verifyhost = FALSE)

crul::set_verbose()
out<-docs_get(x, index = 'MyIndex',id=1)

but this gives me the same error:

Error: 403 - action [cluster:monitor/main] is unauthorized for API key id [HyajjUUU] of user [elastic], this action is granted by the cluster privileges [monitor,manage,all]

The API key that is returned is different to the one I submitted but Im not sure why.

sckott commented 3 years ago

perhaps you have an API key set as an environment variable ?

The host parameter should not have the scheme (https) in it, sorry I had that in my eg above, So should be host="myserver" instead of host="https://myserver" - but I don't think that is the issue here

What do you mean by returned? Returned in that error message above? Is the API key that is returned an API key you are familiar with?

Another debugging option is to set errors="complete" in your connect() call https://docs.ropensci.org/elastic/reference/connect.html#arguments