-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optionally use generated api_key auth to ES #1098
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
import time | ||
|
||
import certifi | ||
import elasticsearch | ||
import urllib3 | ||
|
||
from esrally import exceptions, doc_link | ||
|
@@ -127,18 +128,39 @@ def _is_set(self, client_opts, k): | |
except KeyError: | ||
return False | ||
|
||
def create(self): | ||
import elasticsearch | ||
def _postprocess_client_options(self): | ||
""" | ||
This method is used to do any non init processing of the client options, prior to creating a client | ||
""" | ||
if self._is_set(self.client_options, "use_api_key"): | ||
self._generate_api_key() | ||
|
||
def _generate_api_key(self): | ||
with self._create_sync_client() as instance: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ya i figured you would like that ;) |
||
# an api_key is generated per client, which happens after an initial handshake using an existing auth scheme | ||
# once this key is generated, a new client is created using the api_key client option and http_auth is removed | ||
# the reason the options were not removed in place was because of the logic to coalesce the key tuple into a | ||
# header that the client could use. | ||
api_key_response = instance.security.create_api_key({"name": "rally-api-key"}) | ||
self.client_options.pop("http_auth", None) | ||
self.client_options["api_key"] = (api_key_response["id"], api_key_response["api_key"]) | ||
|
||
def _create_sync_client(self): | ||
return elasticsearch.Elasticsearch(hosts=self.hosts, ssl_context=self.ssl_context, **self.client_options) | ||
|
||
def create(self): | ||
self._postprocess_client_options() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two issues with this that I missed when first eyeballing your draft PR:
Given these two issues I sense that we need a different approach. One option would be to insert a dedicated task at the beginning of a schedule but I sense that's the wrong approach either because the track should be agnostic to how clients authenticate. Maybe let's discuss this on a high-bandwidth medium. |
||
return self._create_sync_client() | ||
|
||
def create_async(self): | ||
import elasticsearch | ||
import esrally.async_connection | ||
import io | ||
import aiohttp | ||
|
||
from elasticsearch.serializer import JSONSerializer | ||
|
||
self._postprocess_client_options() | ||
|
||
class LazyJSONSerializer(JSONSerializer): | ||
def loads(self, s): | ||
meta = RallyAsyncElasticsearch.request_context.get() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would also enter the block if the user specified
use_api_key:false
on the client options. I noticed that we fall into this trap in other places in this class as well and I propose we change this line to:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That method is slightly misleading. It does not check if its set, it just removes the possibility of a key error. It returns the value, if present. Adding a test like so confirms this (and passes).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the semantics of the predicate
is_set
are misleading and maybe we should change it. I still propose we implement this line here differently:This ensures correct behavior depending on the value of
use_api_key
.