# Buggy code
def init(self):
    if Elasticsearch is None:
        raise MissingDependencyError("elasticsearch", version=">=5.0.0,<6.0.0")

    self.elastic_host = getattr(self.parameters, "elastic_host", "127.0.0.1")
    self.elastic_port = getattr(self.parameters, "elastic_port", "9200")
    self.elastic_index = getattr(self.parameters, "elastic_index", "intelmq")
    self.rotate_index = getattr(self.parameters, "rotate_index", False)
    self.use_ssl = getattr(self.parameters, "use_ssl", False)
    self.ssl_ca_certificate = getattr(self.parameters, "ssl_ca_certificate", None)
    self.ssl_show_warnings = getattr(self.parameters, "ssl_show_warnings", True)
    self.elastic_doctype = getattr(self.parameters, "elastic_doctype", "events")
    self.replacement_char = getattr(self.parameters, "replacement_char", None)
    self.flatten_fields = getattr(self.parameters, "flatten_fields", ["extra"])
    if isinstance(self.flatten_fields, str):
        self.flatten_fields = self.flatten_fields.split(",")

    self.set_request_parameters()  # Not all parameters set here are used by the ES client

    self.es = Elasticsearch(
        [{"host": self.elastic_host, "port": self.elastic_port}],
        http_auth=self.auth,
        use_ssl=self.use_ssl,
        verify_certs=self.http_verify_cert,
        ca_certs=self.ssl_ca_certificate,
        ssl_show_warn=self.ssl_show_warnings,
    )

    if self.should_rotate():
        # Use rotating index names - check that the template exists
        if not self.es.indices.exists_template(name=self.elastic_index):
            raise RuntimeError(
                "No template with the name '{}' exists on the Elasticsearch host, "
                "but 'rotate_index' is set. "
                "Have you created the template?".format(self.elastic_index)
            )

    else:
        # Using a single named index. Check that it exists and create it if it doesn't
        if not self.es.indices.exists(self.elastic_index):
            self.es.indices.create(index=self.elastic_index, ignore=400)


# Traceback (elasticsearch.exceptions.RequestError)
======================================================================
ERROR: Tests whether an input event with a time.observation field (and no time.source field) is indexed according to
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/sebastian/dev/intelmq/intelmq/tests/bots/outputs/elasticsearch/test_output.py", line 200, in test_index_detected_from_time_observation
"rotate_index": "daily"})
File "/home/sebastian/dev/intelmq/intelmq/tests/bots/outputs/elasticsearch/test_output.py", line 249, in base_check_expected_index_created
self.con.indices.put_template(name=parameters['elastic_index'], body=SAMPLE_TEMPLATE)
File "/usr/lib/python3.6/site-packages/elasticsearch/client/utils.py", line 76, in _wrapped
return func(*args, params=params, **kwargs)
File "/usr/lib/python3.6/site-packages/elasticsearch/client/indices.py", line 447, in put_template
name), params=params, body=body)
File "/usr/lib/python3.6/site-packages/elasticsearch/transport.py", line 314, in perform_request
status, headers, data = connection.perform_request(method, url, params, body, headers=headers, ignore=ignore, timeout=timeout)
File "/usr/lib/python3.6/site-packages/elasticsearch/connection/http_urllib3.py", line 161, in perform_request
self._raise_error(response.status, raw_data)
File "/usr/lib/python3.6/site-packages/elasticsearch/connection/base.py", line 125, in _raise_error
raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)
elasticsearch.exceptions.RequestError: TransportError(400, 'mapper_parsing_exception', 'Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]')
-------------------- >> begin captured logging << --------------------
urllib3.util.retry: DEBUG: Converted retries value: False -> Retry(total=False, connect=None, read=None, redirect=0, status=None)
urllib3.connectionpool: DEBUG: http://localhost:9200 "HEAD /None-2020-02-02 HTTP/1.1" 404 0
urllib3.util.retry: DEBUG: Converted retries value: False -> Retry(total=False, connect=None, read=None, redirect=0, status=None)
urllib3.connectionpool: DEBUG: http://localhost:9200 "PUT /_template/intelmq HTTP/1.1" 400 942
elasticsearch: WARNING: PUT http://localhost:9200/_template/intelmq [status:400 request:0.013s]
elasticsearch: DEBUG: > {"mappings": {"events": {"properties": {"time.observation": {"type": "date"}, "time.source": {"type": "date"}, "classification.type": {"type": "keyword"}, "source.asn": {"type": "integer"}, "feed.name": {"type": "text"}, "source.ip": {"type": "ip"}}}}, "template": "intelmq-*", "index_patterns": ["intelmq-*"]}
elasticsearch: DEBUG: < {"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]"}],"type":"mapper_parsing_exception","reason":"Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]","caused_by":{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]"}},"status":400}
--------------------- >> end captured logging << ---------------------

======================================================================
ERROR: Tests whether an input event with a time.source field is indexed according to its time.source date.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/sebastian/dev/intelmq/intelmq/tests/bots/outputs/elasticsearch/test_output.py", line 187, in test_index_detected_from_time_source
"rotate_index": "daily"})
File "/home/sebastian/dev/intelmq/intelmq/tests/bots/outputs/elasticsearch/test_output.py", line 249, in base_check_expected_index_created
self.con.indices.put_template(name=parameters['elastic_index'], body=SAMPLE_TEMPLATE)
File "/usr/lib/python3.6/site-packages/elasticsearch/client/utils.py", line 76, in _wrapped
return func(*args, params=params, **kwargs)
File "/usr/lib/python3.6/site-packages/elasticsearch/client/indices.py", line 447, in put_template
name), params=params, body=body)
File "/usr/lib/python3.6/site-packages/elasticsearch/transport.py", line 314, in perform_request
status, headers, data = connection.perform_request(method, url, params, body, headers=headers, ignore=ignore, timeout=timeout)
File "/usr/lib/python3.6/site-packages/elasticsearch/connection/http_urllib3.py", line 161, in perform_request
self._raise_error(response.status, raw_data)
File "/usr/lib/python3.6/site-packages/elasticsearch/connection/base.py", line 125, in _raise_error
raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)
elasticsearch.exceptions.RequestError: TransportError(400, 'mapper_parsing_exception', 'Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]')
-------------------- >> begin captured logging << --------------------
urllib3.util.retry: DEBUG: Converted retries value: False -> Retry(total=False, connect=None, read=None, redirect=0, status=None)
urllib3.connectionpool: DEBUG: http://localhost:9200 "HEAD /None-1869-12-02 HTTP/1.1" 404 0
urllib3.util.retry: DEBUG: Converted retries value: False -> Retry(total=False, connect=None, read=None, redirect=0, status=None)
urllib3.connectionpool: DEBUG: http://localhost:9200 "PUT /_template/intelmq HTTP/1.1" 400 942
elasticsearch: WARNING: PUT http://localhost:9200/_template/intelmq [status:400 request:0.013s]
elasticsearch: DEBUG: > {"mappings": {"events": {"properties": {"time.observation": {"type": "date"}, "time.source": {"type": "date"}, "classification.type": {"type": "keyword"}, "source.asn": {"type": "integer"}, "feed.name": {"type": "text"}, "source.ip": {"type": "ip"}}}}, "template": "intelmq-*", "index_patterns": ["intelmq-*"]}
elasticsearch: DEBUG: < {"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]"}],"type":"mapper_parsing_exception","reason":"Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]","caused_by":{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]"}},"status":400}
--------------------- >> end captured logging << ---------------------

======================================================================
ERROR: Tests whether get_index returns an expected default date
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/sebastian/dev/intelmq/intelmq/tests/bots/outputs/elasticsearch/test_output.py", line 225, in test_index_falls_back_to_default_date
parameters=parameters)
File "/home/sebastian/dev/intelmq/intelmq/tests/bots/outputs/elasticsearch/test_output.py", line 249, in base_check_expected_index_created
self.con.indices.put_template(name=parameters['elastic_index'], body=SAMPLE_TEMPLATE)
File "/usr/lib/python3.6/site-packages/elasticsearch/client/utils.py", line 76, in _wrapped
return func(*args, params=params, **kwargs)
File "/usr/lib/python3.6/site-packages/elasticsearch/client/indices.py", line 447, in put_template
name), params=params, body=body)
File "/usr/lib/python3.6/site-packages/elasticsearch/transport.py", line 314, in perform_request
status, headers, data = connection.perform_request(method, url, params, body, headers=headers, ignore=ignore, timeout=timeout)
File "/usr/lib/python3.6/site-packages/elasticsearch/connection/http_urllib3.py", line 161, in perform_request
self._raise_error(response.status, raw_data)
File "/usr/lib/python3.6/site-packages/elasticsearch/connection/base.py", line 125, in _raise_error
raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)
elasticsearch.exceptions.RequestError: TransportError(400, 'mapper_parsing_exception', 'Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]')
-------------------- >> begin captured logging << --------------------
urllib3.util.retry: DEBUG: Converted retries value: False -> Retry(total=False, connect=None, read=None, redirect=0, status=None)
urllib3.connectionpool: DEBUG: http://localhost:9200 "HEAD /intelmq-2018-09-09 HTTP/1.1" 404 0
urllib3.util.retry: DEBUG: Converted retries value: False -> Retry(total=False, connect=None, read=None, redirect=0, status=None)
urllib3.connectionpool: DEBUG: http://localhost:9200 "PUT /_template/intelmq HTTP/1.1" 400 942
elasticsearch: WARNING: PUT http://localhost:9200/_template/intelmq [status:400 request:0.011s]
elasticsearch: DEBUG: > {"mappings": {"events": {"properties": {"time.observation": {"type": "date"}, "time.source": {"type": "date"}, "classification.type": {"type": "keyword"}, "source.asn": {"type": "integer"}, "feed.name": {"type": "text"}, "source.ip": {"type": "ip"}}}}, "template": "intelmq-*", "index_patterns": ["intelmq-*"]}
elasticsearch: DEBUG: < {"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]"}],"type":"mapper_parsing_exception","reason":"Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]","caused_by":{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters:  [events : {properties={time.observation={type=date}, time.source={type=date}, classification.type={type=keyword}, source.asn={type=integer}, source.ip={type=ip}, feed.name={type=text}}}]"}},"status":400}
--------------------- >> end captured logging << ---------------------

======================================================================
ERROR: Tests whether get_index returns an expected default string
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/sebastian/dev/intelmq/intelmq/tests/bots/outputs/elasticsearch/test_output.py", line 236, in test_index_falls_back_to_default_string
"rotate_index": "daily"})
File "/home/sebastian/dev/intelmq/intelmq/lib/test.py", line 234, in prepare_bot
self.bot = self.bot_reference(self.bot_id)
File "/home/sebastian/dev/intelmq/intelmq/lib/bot.py", line 158, in __init__
self.init()
File "/home/sebastian/dev/intelmq/intelmq/bots/outputs/elasticsearch/output.py", line 99, in init
"Have you created the template?".format(self.elastic_index))
RuntimeError: No template with the name 'intelmq' exists on the Elasticsearch host, but 'rotate_index' is set. Have you created the template?
-------------------- >> begin captured logging << --------------------
test-bot: INFO: ElasticsearchOutputBot initialized with id test-bot and intelmq 2.2.0.alpha.1 and python 3.6.9 (default, Oct 29 2019, 10:39:36) [GCC] as process 4883.
test-bot: INFO: Bot is starting.
test-bot: INFO: Looking for Index template 'intelmq'.
urllib3.util.retry: DEBUG: Converted retries value: False -> Retry(total=False, connect=None, read=None, redirect=0, status=None)
urllib3.connectionpool: DEBUG: Starting new HTTP connection (1): 127.0.0.1:9200
urllib3.connectionpool: DEBUG: http://127.0.0.1:9200 "HEAD /_template/intelmq HTTP/1.1" 404 0
test-bot: ERROR: Bot initialization failed.
Traceback (most recent call last):
File "/home/sebastian/dev/intelmq/intelmq/lib/bot.py", line 158, in __init__
self.init()
File "/home/sebastian/dev/intelmq/intelmq/bots/outputs/elasticsearch/output.py", line 99, in init
"Have you created the template?".format(self.elastic_index))
RuntimeError: No template with the name 'intelmq' exists on the Elasticsearch host, but 'rotate_index' is set. Have you created the template?
test-bot: INFO: Bot stopped.
--------------------- >> end captured logging << ---------------------

----------------------------------------------------------------------
Ran 9 tests in 2.276s

FAILED (errors=4)

# Fixed code
def init(self):
    if Elasticsearch is None:
        raise MissingDependencyError("elasticsearch", version=">=5.0.0,<6.0.0")

    self.elastic_host = getattr(self.parameters, "elastic_host", "127.0.0.1")
    self.elastic_port = getattr(self.parameters, "elastic_port", "9200")
    self.elastic_index = getattr(self.parameters, "elastic_index", "intelmq")
    self.rotate_index = getattr(self.parameters, "rotate_index", False)
    self.use_ssl = getattr(self.parameters, "use_ssl", False)
    self.ssl_ca_certificate = getattr(self.parameters, "ssl_ca_certificate", None)
    self.ssl_show_warnings = getattr(self.parameters, "ssl_show_warnings", True)
    self.replacement_char = getattr(self.parameters, "replacement_char", None)
    self.flatten_fields = getattr(self.parameters, "flatten_fields", ["extra"])
    if isinstance(self.flatten_fields, str):
        self.flatten_fields = self.flatten_fields.split(",")

    self.set_request_parameters()  # Not all parameters set here are used by the ES client

    self.es = Elasticsearch(
        [{"host": self.elastic_host, "port": self.elastic_port}],
        http_auth=self.auth,
        use_ssl=self.use_ssl,
        verify_certs=self.http_verify_cert,
        ca_certs=self.ssl_ca_certificate,
        ssl_show_warn=self.ssl_show_warnings,
    )

    if self.should_rotate():
        # Use rotating index names - check that the template exists
        if not self.es.indices.exists_template(name=self.elastic_index):
            raise RuntimeError(
                "No template with the name '{}' exists on the Elasticsearch host, "
                "but 'rotate_index' is set. "
                "Have you created the template?".format(self.elastic_index)
            )

    else:
        # Using a single named index. Check that it exists and create it if it doesn't
        if not self.es.indices.exists(self.elastic_index):
            self.es.indices.create(index=self.elastic_index, ignore=400)