diff --git a/docs/providers/elasticsearch.md b/docs/providers/elasticsearch.md index c30b1dbb..1f4e08b8 100644 --- a/docs/providers/elasticsearch.md +++ b/docs/providers/elasticsearch.md @@ -8,8 +8,24 @@ Elasticsearch to create an SLO. ```yaml backends: elasticsearch: - api_token: ${DYNATRACE_API_TOKEN} - api_url: ${DYNATRACE_API_URL} + url: ${ELASTICSEARCH_URL} +``` + +Note that `url` can be either a single string (when connecting to a single node) +or a list of strings (when connecting to multiple nodes): + +```yaml +backends: + elasticsearch: + url: https://localhost:9200 +``` + +```yaml +backends: + elasticsearch: + url: + - https://localhost:9200 + - https://localhost:9201 ``` The following methods are available to compute SLOs with the `elasticsearch` diff --git a/slo_generator/backends/elasticsearch.py b/slo_generator/backends/elasticsearch.py index 2b5d4b0e..36c6142c 100644 --- a/slo_generator/backends/elasticsearch.py +++ b/slo_generator/backends/elasticsearch.py @@ -16,6 +16,7 @@ ElasticSearch backend implementation. """ +import copy import logging from elasticsearch import Elasticsearch @@ -38,7 +39,26 @@ class ElasticsearchBackend: def __init__(self, client=None, **es_config): self.client = client if self.client is None: - self.client = Elasticsearch(**es_config) + # Copy the given client configuration and process it to address + # multiple connection setups (such as Elastic Cloud, basic auth, + # multiple nodes, API token...) before actually instantiating the + # client. + # Note: `es_config.copy()` and `dict(es_config)` only make *shallow* + # copies. We require a full nested copy of the configuration to + # work on. + conf = copy.deepcopy(es_config) + url = conf.pop('url', None) + basic_auth = conf.pop('basic_auth', None) + api_key = conf.pop('api_key', None) + if url: + conf['hosts'] = url + if basic_auth: + conf['basic_auth'] = ( + basic_auth['username'], basic_auth['password']) + if api_key: + conf['api_key'] = (api_key['id'], api_key['value']) + # Note: Either `hosts` or `cloud_id` must be specified in v8.x.x + self.client = Elasticsearch(**conf) # pylint: disable=unused-argument def good_bad_ratio(self, timestamp, window, slo_config):