in esrally/client/factory.py [0:0]
def delete_api_keys(es, ids, max_attempts=5):
"""
Deletes the provided list of API key IDs.
:param es: Elasticsearch client to use for connecting.
:param ids: List of API key IDs to delete.
:param max_attempts: The maximum number of attempts to delete the API keys.
:return: True iff all provided key IDs were successfully deleted.
"""
logger = logging.getLogger(__name__)
def raise_exception(failed_ids, cause=None):
msg = f"Could not delete API keys with the following IDs: {failed_ids}"
if cause is not None:
raise exceptions.RallyError(msg) from cause
raise exceptions.RallyError(msg)
# Before ES 7.10, deleting API keys by ID had to be done individually.
# After ES 7.10, a list of API key IDs can be deleted in one request.
version = es.info()["version"]
current_version = versions.Version.from_string(version.get("number", "7.10.0"))
minimum_version = versions.Version.from_string("7.10.0")
deleted = []
remaining = ids
for attempt in range(1, max_attempts + 1):
# pylint: disable=import-outside-toplevel
import elasticsearch
try:
if current_version >= minimum_version or es.is_serverless:
resp = es.security.invalidate_api_key(ids=remaining)
deleted += resp["invalidated_api_keys"]
remaining = [i for i in ids if i not in deleted]
# Like bulk indexing requests, we can get an HTTP 200, but the
# response body could still contain an array of individual errors.
# So, we have to handle the case were some keys weren't deleted, but
# the request overall succeeded (i.e. we didn't encounter an exception)
if attempt < max_attempts:
if resp["error_count"] > 0:
logger.debug(
"Got the following errors on attempt [%s] of [%s]: [%s]. Sleeping...",
attempt,
max_attempts,
resp["error_details"],
)
else:
if remaining:
logger.warning(
"Got the following errors on final attempt to delete API keys: [%s]",
resp["error_details"],
)
raise_exception(remaining)
else:
remaining = [i for i in ids if i not in deleted]
if attempt < max_attempts:
for i in remaining:
es.security.invalidate_api_key(id=i)
deleted.append(i)
else:
if remaining:
raise_exception(remaining)
return True
except elasticsearch.ApiError as e:
if attempt < max_attempts:
logger.debug("Got status code [%s] on attempt [%s] of [%s]. Sleeping...", e.meta.status, attempt, max_attempts)
time.sleep(1)
else:
raise_exception(remaining, cause=e)
except Exception as e:
if attempt < max_attempts:
logger.debug("Got error on attempt [%s] of [%s]. Sleeping...", attempt, max_attempts)
time.sleep(1)
else:
raise_exception(remaining, cause=e)