From b4820bf1316295f3f7ccec385b6607256399fb0f Mon Sep 17 00:00:00 2001 From: Pawel Szkamruk Date: Tue, 28 Feb 2023 16:21:51 +0100 Subject: [PATCH 1/8] HEC exporter tests - working version -happy path scenarios --- exporter/splunkhecexporter/test/__init__.py | 0 exporter/splunkhecexporter/test/common.py | 284 ++++++++++++++++++ .../splunkhecexporter/test/config/config.yaml | 57 ++++ .../test/config/config_data.py | 0 exporter/splunkhecexporter/test/conftest.py | 57 ++++ .../test/e2e_tests/__init__.py | 0 .../e2e_tests/test_hec_exporter_positive.py | 213 +++++++++++++ .../splunkhecexporter/test/event_generator.py | 85 ++++++ exporter/splunkhecexporter/test/pytest.ini | 3 + .../splunkhecexporter/test/requirements.txt | 2 + 10 files changed, 701 insertions(+) create mode 100644 exporter/splunkhecexporter/test/__init__.py create mode 100644 exporter/splunkhecexporter/test/common.py create mode 100644 exporter/splunkhecexporter/test/config/config.yaml create mode 100644 exporter/splunkhecexporter/test/config/config_data.py create mode 100644 exporter/splunkhecexporter/test/conftest.py create mode 100644 exporter/splunkhecexporter/test/e2e_tests/__init__.py create mode 100644 exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py create mode 100644 exporter/splunkhecexporter/test/event_generator.py create mode 100644 exporter/splunkhecexporter/test/pytest.ini create mode 100644 exporter/splunkhecexporter/test/requirements.txt diff --git a/exporter/splunkhecexporter/test/__init__.py b/exporter/splunkhecexporter/test/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/exporter/splunkhecexporter/test/common.py b/exporter/splunkhecexporter/test/common.py new file mode 100644 index 000000000000..17792768231c --- /dev/null +++ b/exporter/splunkhecexporter/test/common.py @@ -0,0 +1,284 @@ +""" +Copyright 2018-2019 Splunk, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import json +import logging +import time +import requests +import os +import sys +from requests.packages.urllib3.util.retry import Retry +from requests.adapters import HTTPAdapter + + +TIMEROUT = 500 + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +formatter = logging.Formatter('%(asctime)s - %(name)s -' + + ' %(levelname)s - %(message)s') +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter(formatter) +logger.addHandler(handler) + + +def check_events_from_splunk(index="circleci_events", + start_time="-1h@h", + end_time="now", + url="", + user="", + query="", + password=""): + ''' + send a search request to splunk and return the events from the result + ''' + #logger.info("search query = " + str(query)) + events = _collect_events(query, start_time, end_time, url, user, password) + + return events + +def check_metrics_from_splunk(index="circleci_metrics", + start_time="-1h@h", + end_time="now", + url="", + user="", + password="", + metric_name=""): + ''' + send a search api request to splunk to check for values associated with a given metric and dimension + ''' + logger.debug("Calling _collect_metrics ") + events = _collect_metrics(start_time, end_time, url, user, password, index, metric_name) + + return events + + +def create_index_in_splunk(index="", + url="", + user="", + password=""): + ''' + Send a request to a Splunk instance to create an index + @param: index (index to be deleted) + @param: url (splunkd rest api url) + @param: user (splunk username) + @param: password (splunk password) + returns True/False + ''' + + search_url = '{0}/services/data/indexes/{1}?output_mode=json'.format(url, index) + logger.debug('requesting: %s', search_url) + data = { + 'name': index + } + + create_job = _requests_retry_session().post( + search_url, + auth=(user, password), + verify=False, data=data) + + if create_job.status_code == 201: + logger.info('The index: %s successfully created', index) + elif create_job.status_code == 409: + logger.info('The index: %s already exits', index) + else: + logger.info('The index: {0} not created, exit code is {1}'.format(index, create_job.status_code)) + return False + + return True + + +def delete_index_in_splunk(index="", + user="", + url="", + password=""): + ''' + Send a request to a Splunk instance to delete an index + @param: index (index to be deleted) + @param: url (splunkd rest api url) + @param: user (splunk username) + @param: password (splunk password) + returns True/False + ''' + + search_url = '{0}/services/data/indexes/{1}?output_mode=json'.format(url, index) + logger.debug('requesting: %s', search_url) + data = { + 'name': index + } + + create_job = _requests_retry_session().delete( + search_url, + auth=(user, password), + verify=False, data=data) + + if create_job.status_code == 200: + logger.info('The index: %s successfully deleted', index) + elif create_job.status_code == 409: + logger.info('The index: %s already disabled', index) + else: + return False + + return True + + +def _collect_events(query, start_time, end_time, url="", user="", password=""): + ''' + Collect events by running the given search query + @param: query (search query) + @param: start_time (search start time) + @param: end_time (search end time) + returns events + ''' + + search_url = '{0}/services/search/jobs?output_mode=json'.format( + url) + logger.debug('requesting: %s', search_url) + data = { + 'search': query, + 'earliest_time': start_time, + 'latest_time': end_time, + } + + create_job = _requests_retry_session().post( + search_url, + auth=(user, password), + verify=False, data=data) + _check_request_status(create_job) + + json_res = create_job.json() + job_id = json_res['sid'] + events = _wait_for_job_and__get_events(job_id, url, user, password) + + return events + +def _collect_metrics(start_time, end_time, url="", user="", password="", index="", metric_name=""): + ''' + Verify metrics by running the given api query + @param: dimension (metric dimension) + @param: metric_name (metric name) + @param: start_time (search start time) + @param: end_time (search end time) + returns events + ''' + api_url = url + '/services/catalog/metricstore/dimensions/host/values?filter=index%3d' + index + '&metric_name=' + metric_name + '&earliest=' + start_time + '&latest=' + end_time + '&output_mode=json'.format( + url) + logger.debug('requesting: %s', api_url) + + create_job = _requests_retry_session().get( + api_url, + auth=(user, password), + verify=False + ) + + _check_request_status(create_job) + + json_res = create_job.json() + + events = json_res['entry'] + #logger.info('events: %s', events) + + return events + + +def _wait_for_job_and__get_events(job_id, url="", user="", password=""): + ''' + Wait for the search job to finish and collect the result events + @param: job_id + returns events + ''' + events = [] + job_url = '{0}/services/search/jobs/{1}?output_mode=json'.format( + url, str(job_id)) + logger.debug('requesting: %s', job_url) + + for _ in range(TIMEROUT): + res = _requests_retry_session().get( + job_url, + auth=(user, password), + verify=False) + _check_request_status(res) + + job_res = res.json() + dispatch_state = job_res['entry'][0]['content']['dispatchState'] + + if dispatch_state == 'DONE': + events = _get_events(job_id, url, user, password) + break + if dispatch_state == 'FAILED': + raise Exception('Search job: {0} failed'.format(job_url)) + time.sleep(1) + + return events + + +def _get_events(job_id, url="", user="", password=""): + ''' + collect the result events from a search job + @param: job_id + returns events + ''' + event_url = '{0}/services/search/jobs/{1}/events?output_mode=json'.format( + url, str(job_id)) + logger.debug('requesting: %s', event_url) + + event_job = _requests_retry_session().get( + event_url, auth=(user, password), + verify=False) + _check_request_status(event_job) + + event_job_json = event_job.json() + events = event_job_json['results'] + logger.debug("Events from get_events method returned %s events", + len(events)) + + return events + + +def _check_request_status(req_obj): + ''' + check if a request is successful + @param: req_obj + returns True/False + ''' + if not req_obj.ok: + raise Exception('status code: {0} \n details: {1}'.format( + str(req_obj.status_code), req_obj.text)) + + +def _requests_retry_session( + retries=10, + backoff_factor=0.1, + status_forcelist=(500, 502, 504)): + ''' + create a retry session for HTTP/HTTPS requests + @param: retries (num of retry time) + @param: backoff_factor + @param: status_forcelist (list of error status code to trigger retry) + @param: session + returns: session + ''' + session = requests.Session() + retry = Retry( + total=int(retries), + backoff_factor=backoff_factor, + status_forcelist=status_forcelist, + ) + adapter = HTTPAdapter(max_retries=retry) + session.mount('http://', adapter) + session.mount('https://', adapter) + + return session diff --git a/exporter/splunkhecexporter/test/config/config.yaml b/exporter/splunkhecexporter/test/config/config.yaml new file mode 100644 index 000000000000..bb781fc55908 --- /dev/null +++ b/exporter/splunkhecexporter/test/config/config.yaml @@ -0,0 +1,57 @@ +receivers: + filelog: + include: [ ./*.json ] + splunk_hec/logs: + endpoint: 0.0.0.0:8883 + splunk_hec/metrics: + endpoint: 0.0.0.0:8884 + hostmetrics: + collection_interval: 30s + scrapers: + cpu: + disk: + load: + filesystem: + memory: + network: +exporters: + splunk_hec: + # Splunk HTTP Event Collector token. + token: "00000000-0000-0000-0000-000000000000" + # URL to a Splunk instance to send data to. + endpoint: "https://10.202.11.213:8088/services/collector" + index: "metrics" + health_path: "/services/collector/health" + health_check_enabled: true + tls: + insecure_skip_verify: true + splunk_hec/logs: + # Splunk HTTP Event Collector token. + token: "00000000-0000-0000-0000-000000000000" + # URL to a Splunk instance to send data to. + endpoint: "https://10.202.11.213:8088/services/collector" + sourcetype: "filelog_sourcetype" + index: "file_logs" + health_path: "/services/collector/health" + health_check_enabled: true + tls: + insecure_skip_verify: true + logging: + loglevel: debug +service: + telemetry: + logs: + level: "debug" + pipelines: + metrics: + receivers: [splunk_hec/metrics] + exporters: [splunk_hec, logging] + metrics/2: + receivers: [hostmetrics] + exporters: [splunk_hec, logging] + logs: + receivers: [splunk_hec/logs] + exporters: [splunk_hec, logging] + logs/2: + receivers: [ filelog ] + exporters: [ splunk_hec/logs, logging ] diff --git a/exporter/splunkhecexporter/test/config/config_data.py b/exporter/splunkhecexporter/test/config/config_data.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/exporter/splunkhecexporter/test/conftest.py b/exporter/splunkhecexporter/test/conftest.py new file mode 100644 index 000000000000..2b546109b896 --- /dev/null +++ b/exporter/splunkhecexporter/test/conftest.py @@ -0,0 +1,57 @@ +""" +Copyright 2018-2019 Splunk, Inc.. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import pytest +from common import check_events_from_splunk + + +def pytest_addoption(parser): + parser.addoption("--splunkd-url", + help="splunkd url used to send test data to. \ + Eg: https://localhost:8089", + default="https://localhost:8089") + parser.addoption("--splunk-user", + help="splunk username", + default="admin") + parser.addoption("--splunk-password", + help="splunk user password", + default="password") + + +# Print events ingested in splunk for debugging +def pytest_unconfigure(config): + indexes = ["main", "sck-metrics"] + for index in indexes: + search_query = "index=" + index + " | fields *" + events = check_events_from_splunk(start_time="-1h@h", + url=config.getoption("--splunkd-url"), + user=config.getoption("--splunk-user"), + query=["search {0}".format( + search_query)], + password=config.getoption("--splunk-password")) + print("index=" + index + " event count=" + str(len(events))) + # for event in events: + # print(event) + + +@pytest.fixture(scope="function") +def setup(request): + config = {} + config["splunkd_url"] = request.config.getoption("--splunkd-url") + config["splunk_user"] = request.config.getoption("--splunk-user") + config["splunk_password"] = request.config.getoption("--splunk-password") + + return config diff --git a/exporter/splunkhecexporter/test/e2e_tests/__init__.py b/exporter/splunkhecexporter/test/e2e_tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py b/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py new file mode 100644 index 000000000000..fbc8b682bac1 --- /dev/null +++ b/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py @@ -0,0 +1,213 @@ +import time + +import pytest +import logging +import sys +import os +from ..event_generator import send_event, send_metric, send_event_with_timeoffset, add_filelog_event +from ..common import check_events_from_splunk, check_metrics_from_splunk + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +formatter = logging.Formatter('%(message)s') +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter(formatter) +logger.addHandler(handler) + + +# @pytest.mark.skip +@pytest.mark.parametrize("test_data,expected", [ + ("test_data", 1) +]) +def test_splunk_event_metadata_as_string(setup, test_data, expected): + ''' + What is this test doing + ''' + logger.info("\n----------") + logger.info("testing test_splunk_index input={0} expected={1} event(s)".format( + test_data, expected)) + index = "main" + source = "source_test_1" + sourcetype = "sourcetype_test_1" + send_event(index, source, sourcetype, test_data) + search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source + logger.info(f"SPL: {search_query}") + events = check_events_from_splunk(start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format( + search_query)], + password=setup["splunk_password"]) + logger.info("Splunk received %s events in the last minute", + len(events)) + assert len(events) >= expected + + logger.info("Test Finished") + + +# @pytest.mark.skip +def test_splunk_event_json_object(setup): + ''' + What is this test doing + ''' + logger.info("Starting second test!") + logger.info("\n----------") + index = "sck-otel" + source = "source_test_2" + sourcetype = "sourcetype_test_2" + json_data = { + "test_name": "Test 2b timestamp", + "field1": "test", + "field2": 155, + "index": index + } + + send_event(index, source, sourcetype, json_data) + search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source + logger.info(f"SPL: {search_query}") + events = check_events_from_splunk(start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format( + search_query)], + password=setup["splunk_password"]) + logger.info("Splunk received %s events in the last minute", + len(events)) + assert len(events) >= 1 + logger.info("Test Finished") + + +# @pytest.mark.skip +def test_splunk_event_timestamp(setup): + ''' + What is this test doing + ''' + logger.info("Starting third test!") + logger.info("\n----------") + index = "sck-otel" + source = "source_test_3" + sourcetype = "sourcetype_test_3" + event_timestamp = time.time() - 1800 + json_data = { + "time": event_timestamp, + "test_name": "Test timestamp", + "index": index + } + send_event_with_timeoffset(index, source, sourcetype, json_data, event_timestamp) + search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source + logger.info(f"SPL: {search_query}") + events = check_events_from_splunk(start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format( + search_query)], + password=setup["splunk_password"]) + past_events = check_events_from_splunk(start_time="-30m@m", + end_time="-29m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format( + search_query)], + password=setup["splunk_password"]) + logger.info("Splunk received %s events in the last minute", + len(events)) + assert len(events) == 0 + assert len(past_events) >= 1 + logger.info("Test Finished") + + +# @pytest.mark.skip +@pytest.mark.parametrize("data,expected_event_count", [("This is the event!", 1), + ('{"test_name": "json_event","source": "file_log"}', 2)]) +def test_events_source_file_log_receiver_text(setup, data, expected_event_count): + ''' + What is this test doing + ''' + logger.info("Starting file log receiver test!") + logger.info("\n----------") + index = "file_logs" + sourcetype = "filelog_sourcetype" + + search_query = "index=" + index + " sourcetype=" + sourcetype + logger.info(f"SPL: {search_query}") + events = check_events_from_splunk(start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format( + search_query)], + password=setup["splunk_password"]) + logger.info("Splunk received %s events in the last minute", + len(events)) + assert len(events) == expected_event_count - 1 + add_filelog_event(data) + + events = check_events_from_splunk(start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format( + search_query)], + password=setup["splunk_password"]) + logger.info("Splunk received %s events in the last minute", + len(events)) + assert len(events) >= expected_event_count + logger.info("Test Finished") + + +# @pytest.mark.skip +@pytest.mark.parametrize("metric_name", [ + "system.filesystem.inodes.usage", + "system.filesystem.usage", + "system.memory.usage", + "system.network.connections", + "system.network.dropped", + "system.network.errors", + "system.network.io", + "system.network.packets", + "system.cpu.load_average.1m", + "system.cpu.load_average.5m", + "system.cpu.load_average.15m" + +]) +def test_splunk_hostmetric_events(setup, metric_name): + ''' + What is this test doing + ''' + logger.info("\n----------") + index = "metrics" + source = "source_test_2" + sourcetype = "sourcetype_test_2" + + send_metric(index, source, sourcetype) + events = check_metrics_from_splunk(start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + metric_name=metric_name, + index=index, + password=setup["splunk_password"]) + logger.info("Splunk received %s events in the last minute", + len(events)) + assert len(events) >= 1 + logger.info("Test Finished") + + +# @pytest.mark.skip +def test_splunk_metric_events(setup): + ''' + What is this test doing + ''' + logger.info("\n----------") + index = "sck-metrics" + source = "source_test_metric" + sourcetype = "sourcetype_test_metric" + + send_metric(index, source, sourcetype) + events = check_metrics_from_splunk(start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + metric_name="test.metric", + index=index, + password=setup["splunk_password"]) + logger.info("Splunk received %s events in the last minute", + len(events)) + assert len(events) >= 1 + logger.info("Test Finished") diff --git a/exporter/splunkhecexporter/test/event_generator.py b/exporter/splunkhecexporter/test/event_generator.py new file mode 100644 index 000000000000..10e1f296b6a7 --- /dev/null +++ b/exporter/splunkhecexporter/test/event_generator.py @@ -0,0 +1,85 @@ +import logging +import time + +import requests + + +def wait_for_event_to_be_indexed_in_splunk(): + logging.info("Wating for event indexing") + time.sleep(3) + + +def send_event_old(): + print("sending event") + json_data = {"event": "Pony 8 has left the barn", "index": "main"} + requests.post("http://0.0.0.0:8883", json=json_data, verify=False) + wait_for_event_to_be_indexed_in_splunk() + + +def send_event(index, source, source_type, data): + print("sending event") + json_data = {"event": data, + # "time": 1677241967.317544, + "index": index, + "host": "localhost", + "source": source, + "sourcetype": source_type, + } + requests.post("http://0.0.0.0:8883", json=json_data, verify=False) + wait_for_event_to_be_indexed_in_splunk() + + +def send_event_with_timeoffset(index, source, source_type, data, time): + print("sending event") + json_data = {"event": data, + "time": time, + "index": index, + "host": "localhost", + "source": source, + "sourcetype": source_type, + } + requests.post("http://0.0.0.0:8883", json=json_data, verify=False) + wait_for_event_to_be_indexed_in_splunk() + + +def send_metric(index, source, source_type): + print("sending metric") + fields_1 = {"metric_name:test.metric": 123, + "k0": "v0", + "k1": "v1"} + + fields_2 = {"region": "us-west-1", "datacenter": "dc1", "rack": "63", "os": "Ubuntu16.10", "arch": "x64", + "team": "LON", "service": "6", "service_version": "0", "service_environment": "test", + "path": "/dev/sda1", + "fstype": "ext3", "metric_name:cpu.usr": 11.12, "metric_name:cpu.sys": 12.23, + "metric_name:cpu.idle": 13.34} + + json_data = { + "host": "localhost", + "source": source, + "sourcetype": source_type, + "index": index, + "event": "metric", + "fields": fields_1 + } + requests.post("http://127.0.0.1:8884", json=json_data, verify=False) + wait_for_event_to_be_indexed_in_splunk() + + +def add_filelog_event(data): + print("adding file event") + f = open("./../../../bin/test_file.json", "a") + # f.write(data) + # f.close() + + for line in data: + f.write(line) + f.write("\n") + f.close() + wait_for_event_to_be_indexed_in_splunk() + + +# if __name__ == "__main__": + # send_event() + # send_metric() + # add_filelog_event() diff --git a/exporter/splunkhecexporter/test/pytest.ini b/exporter/splunkhecexporter/test/pytest.ini new file mode 100644 index 000000000000..f31b9cd5ccf3 --- /dev/null +++ b/exporter/splunkhecexporter/test/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +addopts = -rfps --disable-pytest-warnings --continue-on-collection-errors --log-level=DEBUG -vv + diff --git a/exporter/splunkhecexporter/test/requirements.txt b/exporter/splunkhecexporter/test/requirements.txt new file mode 100644 index 000000000000..16d3b778913e --- /dev/null +++ b/exporter/splunkhecexporter/test/requirements.txt @@ -0,0 +1,2 @@ +pytest +requests \ No newline at end of file From fc9fcbbd77b6e43c406a142c1a6a7025a3bb16c4 Mon Sep 17 00:00:00 2001 From: Pawel Szkamruk Date: Wed, 1 Mar 2023 16:37:44 +0100 Subject: [PATCH 2/8] refactoring + code formatted using black --- exporter/splunkhecexporter/test/common.py | 230 ++++++++------- .../test/config/config_data.py | 6 + exporter/splunkhecexporter/test/conftest.py | 39 +-- .../e2e_tests/test_hec_exporter_positive.py | 272 +++++++++--------- .../splunkhecexporter/test/event_generator.py | 73 ++--- 5 files changed, 320 insertions(+), 300 deletions(-) diff --git a/exporter/splunkhecexporter/test/common.py b/exporter/splunkhecexporter/test/common.py index 17792768231c..f60eed498265 100644 --- a/exporter/splunkhecexporter/test/common.py +++ b/exporter/splunkhecexporter/test/common.py @@ -28,107 +28,106 @@ logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) -formatter = logging.Formatter('%(asctime)s - %(name)s -' + - ' %(levelname)s - %(message)s') +formatter = logging.Formatter( + "%(asctime)s - %(name)s -" + " %(levelname)s - %(message)s" +) handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) logger.addHandler(handler) -def check_events_from_splunk(index="circleci_events", - start_time="-1h@h", - end_time="now", - url="", - user="", - query="", - password=""): - ''' +def check_events_from_splunk( + start_time="-1h@h", + end_time="now", + url="", + user="", + query="", + password="", +): + """ send a search request to splunk and return the events from the result - ''' - #logger.info("search query = " + str(query)) + """ + logger.info("search query = " + str(query)) events = _collect_events(query, start_time, end_time, url, user, password) return events -def check_metrics_from_splunk(index="circleci_metrics", - start_time="-1h@h", - end_time="now", - url="", - user="", - password="", - metric_name=""): - ''' + +def check_metrics_from_splunk( + index="metrics", + start_time="-1h@h", + end_time="now", + url="", + user="", + password="", + metric_name="", +): + """ send a search api request to splunk to check for values associated with a given metric and dimension - ''' + """ logger.debug("Calling _collect_metrics ") - events = _collect_metrics(start_time, end_time, url, user, password, index, metric_name) + events = _collect_metrics( + start_time, end_time, url, user, password, index, metric_name + ) return events -def create_index_in_splunk(index="", - url="", - user="", - password=""): - ''' +def create_index_in_splunk(index="", url="", user="", password=""): + """ Send a request to a Splunk instance to create an index @param: index (index to be deleted) @param: url (splunkd rest api url) @param: user (splunk username) @param: password (splunk password) returns True/False - ''' + """ - search_url = '{0}/services/data/indexes/{1}?output_mode=json'.format(url, index) - logger.debug('requesting: %s', search_url) - data = { - 'name': index - } + search_url = "{0}/services/data/indexes/{1}?output_mode=json".format(url, index) + logger.debug("requesting: %s", search_url) + data = {"name": index} create_job = _requests_retry_session().post( - search_url, - auth=(user, password), - verify=False, data=data) + search_url, auth=(user, password), verify=False, data=data + ) if create_job.status_code == 201: - logger.info('The index: %s successfully created', index) + logger.info("The index: %s successfully created", index) elif create_job.status_code == 409: - logger.info('The index: %s already exits', index) + logger.info("The index: %s already exits", index) else: - logger.info('The index: {0} not created, exit code is {1}'.format(index, create_job.status_code)) + logger.info( + "The index: {0} not created, exit code is {1}".format( + index, create_job.status_code + ) + ) return False return True -def delete_index_in_splunk(index="", - user="", - url="", - password=""): - ''' +def delete_index_in_splunk(index="", user="", url="", password=""): + """ Send a request to a Splunk instance to delete an index @param: index (index to be deleted) @param: url (splunkd rest api url) @param: user (splunk username) @param: password (splunk password) returns True/False - ''' + """ - search_url = '{0}/services/data/indexes/{1}?output_mode=json'.format(url, index) - logger.debug('requesting: %s', search_url) - data = { - 'name': index - } + search_url = "{0}/services/data/indexes/{1}?output_mode=json".format(url, index) + logger.debug("requesting: %s", search_url) + data = {"name": index} create_job = _requests_retry_session().delete( - search_url, - auth=(user, password), - verify=False, data=data) + search_url, auth=(user, password), verify=False, data=data + ) if create_job.status_code == 200: - logger.info('The index: %s successfully deleted', index) + logger.info("The index: %s successfully deleted", index) elif create_job.status_code == 409: - logger.info('The index: %s already disabled', index) + logger.info("The index: %s already disabled", index) else: return False @@ -136,141 +135,150 @@ def delete_index_in_splunk(index="", def _collect_events(query, start_time, end_time, url="", user="", password=""): - ''' + """ Collect events by running the given search query @param: query (search query) @param: start_time (search start time) @param: end_time (search end time) returns events - ''' + """ - search_url = '{0}/services/search/jobs?output_mode=json'.format( - url) - logger.debug('requesting: %s', search_url) + search_url = "{0}/services/search/jobs?output_mode=json".format(url) + logger.debug("requesting: %s", search_url) data = { - 'search': query, - 'earliest_time': start_time, - 'latest_time': end_time, + "search": query, + "earliest_time": start_time, + "latest_time": end_time, } create_job = _requests_retry_session().post( - search_url, - auth=(user, password), - verify=False, data=data) + search_url, auth=(user, password), verify=False, data=data + ) _check_request_status(create_job) json_res = create_job.json() - job_id = json_res['sid'] + job_id = json_res["sid"] events = _wait_for_job_and__get_events(job_id, url, user, password) return events -def _collect_metrics(start_time, end_time, url="", user="", password="", index="", metric_name=""): - ''' + +def _collect_metrics( + start_time, end_time, url="", user="", password="", index="", metric_name="" +): + """ Verify metrics by running the given api query @param: dimension (metric dimension) @param: metric_name (metric name) @param: start_time (search start time) @param: end_time (search end time) returns events - ''' - api_url = url + '/services/catalog/metricstore/dimensions/host/values?filter=index%3d' + index + '&metric_name=' + metric_name + '&earliest=' + start_time + '&latest=' + end_time + '&output_mode=json'.format( - url) - logger.debug('requesting: %s', api_url) + """ + api_url = ( + url + + "/services/catalog/metricstore/dimensions/host/values?filter=index%3d" + + index + + "&metric_name=" + + metric_name + + "&earliest=" + + start_time + + "&latest=" + + end_time + + "&output_mode=json".format(url) + ) + logger.debug("requesting: %s", api_url) create_job = _requests_retry_session().get( - api_url, - auth=(user, password), - verify=False + api_url, auth=(user, password), verify=False ) _check_request_status(create_job) json_res = create_job.json() - events = json_res['entry'] - #logger.info('events: %s', events) + events = json_res["entry"] + # logger.info('events: %s', events) return events def _wait_for_job_and__get_events(job_id, url="", user="", password=""): - ''' + """ Wait for the search job to finish and collect the result events @param: job_id returns events - ''' + """ events = [] - job_url = '{0}/services/search/jobs/{1}?output_mode=json'.format( - url, str(job_id)) - logger.debug('requesting: %s', job_url) + job_url = "{0}/services/search/jobs/{1}?output_mode=json".format(url, str(job_id)) + logger.debug("requesting: %s", job_url) for _ in range(TIMEROUT): res = _requests_retry_session().get( - job_url, - auth=(user, password), - verify=False) + job_url, auth=(user, password), verify=False + ) _check_request_status(res) job_res = res.json() - dispatch_state = job_res['entry'][0]['content']['dispatchState'] + dispatch_state = job_res["entry"][0]["content"]["dispatchState"] - if dispatch_state == 'DONE': + if dispatch_state == "DONE": events = _get_events(job_id, url, user, password) break - if dispatch_state == 'FAILED': - raise Exception('Search job: {0} failed'.format(job_url)) + if dispatch_state == "FAILED": + raise Exception("Search job: {0} failed".format(job_url)) time.sleep(1) return events def _get_events(job_id, url="", user="", password=""): - ''' + """ collect the result events from a search job @param: job_id returns events - ''' - event_url = '{0}/services/search/jobs/{1}/events?output_mode=json'.format( - url, str(job_id)) - logger.debug('requesting: %s', event_url) + """ + event_url = "{0}/services/search/jobs/{1}/events?output_mode=json".format( + url, str(job_id) + ) + logger.debug("requesting: %s", event_url) event_job = _requests_retry_session().get( - event_url, auth=(user, password), - verify=False) + event_url, auth=(user, password), verify=False + ) _check_request_status(event_job) event_job_json = event_job.json() - events = event_job_json['results'] - logger.debug("Events from get_events method returned %s events", - len(events)) + events = event_job_json["results"] + logger.debug("Events from get_events method returned %s events", len(events)) return events def _check_request_status(req_obj): - ''' + """ check if a request is successful @param: req_obj returns True/False - ''' + """ if not req_obj.ok: - raise Exception('status code: {0} \n details: {1}'.format( - str(req_obj.status_code), req_obj.text)) + raise Exception( + "status code: {0} \n details: {1}".format( + str(req_obj.status_code), req_obj.text + ) + ) def _requests_retry_session( - retries=10, - backoff_factor=0.1, - status_forcelist=(500, 502, 504)): - ''' + retries=10, backoff_factor=0.1, status_forcelist=(500, 502, 504) +): + """ create a retry session for HTTP/HTTPS requests @param: retries (num of retry time) @param: backoff_factor @param: status_forcelist (list of error status code to trigger retry) @param: session returns: session - ''' + """ session = requests.Session() retry = Retry( total=int(retries), @@ -278,7 +286,7 @@ def _requests_retry_session( status_forcelist=status_forcelist, ) adapter = HTTPAdapter(max_retries=retry) - session.mount('http://', adapter) - session.mount('https://', adapter) + session.mount("http://", adapter) + session.mount("https://", adapter) return session diff --git a/exporter/splunkhecexporter/test/config/config_data.py b/exporter/splunkhecexporter/test/config/config_data.py index e69de29bb2d1..633cb6819563 100644 --- a/exporter/splunkhecexporter/test/config/config_data.py +++ b/exporter/splunkhecexporter/test/config/config_data.py @@ -0,0 +1,6 @@ +# indexes +EVENT_INDEX_1 = "main" +EVENT_INDEX_2 = "sck-otel" +EVENT_INDEX_FILE_LOG = "file_logs" +METRICS_INDEX_HOST_METRICS = "metrics" +METRICS_INDEX_METRICS_ENDPOINT = "sck-metrics" diff --git a/exporter/splunkhecexporter/test/conftest.py b/exporter/splunkhecexporter/test/conftest.py index 2b546109b896..1a2c0cfd9022 100644 --- a/exporter/splunkhecexporter/test/conftest.py +++ b/exporter/splunkhecexporter/test/conftest.py @@ -15,34 +15,41 @@ """ import pytest +import config.config_data as config_data from common import check_events_from_splunk def pytest_addoption(parser): - parser.addoption("--splunkd-url", - help="splunkd url used to send test data to. \ + parser.addoption( + "--splunkd-url", + help="splunkd url used to send test data to. \ Eg: https://localhost:8089", - default="https://localhost:8089") - parser.addoption("--splunk-user", - help="splunk username", - default="admin") - parser.addoption("--splunk-password", - help="splunk user password", - default="password") + default="https://localhost:8089", + ) + parser.addoption("--splunk-user", help="splunk username", default="admin") + parser.addoption( + "--splunk-password", help="splunk user password", default="password" + ) # Print events ingested in splunk for debugging def pytest_unconfigure(config): - indexes = ["main", "sck-metrics"] + indexes = [ + config_data.EVENT_INDEX_1, + config_data.EVENT_INDEX_2, + config_data.EVENT_INDEX_FILE_LOG, + ] for index in indexes: search_query = "index=" + index + " | fields *" - events = check_events_from_splunk(start_time="-1h@h", - url=config.getoption("--splunkd-url"), - user=config.getoption("--splunk-user"), - query=["search {0}".format( - search_query)], - password=config.getoption("--splunk-password")) + events = check_events_from_splunk( + start_time="-1h@h", + url=config.getoption("--splunkd-url"), + user=config.getoption("--splunk-user"), + query=["search {0}".format(search_query)], + password=config.getoption("--splunk-password"), + ) print("index=" + index + " event count=" + str(len(events))) + # debug print all events # for event in events: # print(event) diff --git a/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py b/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py index fbc8b682bac1..b779b085d801 100644 --- a/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py +++ b/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py @@ -3,43 +3,44 @@ import pytest import logging import sys -import os -from ..event_generator import send_event, send_metric, send_event_with_timeoffset, add_filelog_event +import config.config_data as config +from ..event_generator import ( + send_event, + send_metric, + send_event_with_time_offset, + add_filelog_event, +) from ..common import check_events_from_splunk, check_metrics_from_splunk logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) -formatter = logging.Formatter('%(message)s') +formatter = logging.Formatter("%(message)s") handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) logger.addHandler(handler) # @pytest.mark.skip -@pytest.mark.parametrize("test_data,expected", [ - ("test_data", 1) -]) +@pytest.mark.parametrize("test_data,expected", [("test_data", 1)]) def test_splunk_event_metadata_as_string(setup, test_data, expected): - ''' + """ What is this test doing - ''' - logger.info("\n----------") - logger.info("testing test_splunk_index input={0} expected={1} event(s)".format( - test_data, expected)) - index = "main" + - check text event received via event endpoint + """ + logger.info("-- Starting: check text event received via event endpoint --") + index = config.EVENT_INDEX_1 source = "source_test_1" sourcetype = "sourcetype_test_1" send_event(index, source, sourcetype, test_data) search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source - logger.info(f"SPL: {search_query}") - events = check_events_from_splunk(start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format( - search_query)], - password=setup["splunk_password"]) - logger.info("Splunk received %s events in the last minute", - len(events)) + events = check_events_from_splunk( + start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format(search_query)], + password=setup["splunk_password"], + ) + logger.info("Splunk received %s events in the last minute", len(events)) assert len(events) >= expected logger.info("Test Finished") @@ -47,167 +48,176 @@ def test_splunk_event_metadata_as_string(setup, test_data, expected): # @pytest.mark.skip def test_splunk_event_json_object(setup): - ''' - What is this test doing - ''' - logger.info("Starting second test!") - logger.info("\n----------") - index = "sck-otel" + """ + What is this test doing + - check json event received via event endpoint + """ + logger.info("-- Starting: check json event received via event endpoint --") + index = config.EVENT_INDEX_2 source = "source_test_2" sourcetype = "sourcetype_test_2" json_data = { "test_name": "Test 2b timestamp", "field1": "test", "field2": 155, - "index": index + "index": index, } send_event(index, source, sourcetype, json_data) search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source - logger.info(f"SPL: {search_query}") - events = check_events_from_splunk(start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format( - search_query)], - password=setup["splunk_password"]) - logger.info("Splunk received %s events in the last minute", - len(events)) + events = check_events_from_splunk( + start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format(search_query)], + password=setup["splunk_password"], + ) + logger.info("Splunk received %s events in the last minute", len(events)) assert len(events) >= 1 logger.info("Test Finished") # @pytest.mark.skip def test_splunk_event_timestamp(setup): - ''' - What is this test doing - ''' - logger.info("Starting third test!") - logger.info("\n----------") - index = "sck-otel" + """ + What is this test doing + - check event timestamp test + """ + logger.info("-- Starting: check event timestamp test --") + index = config.EVENT_INDEX_2 source = "source_test_3" sourcetype = "sourcetype_test_3" event_timestamp = time.time() - 1800 json_data = { "time": event_timestamp, "test_name": "Test timestamp", - "index": index + "index": index, } - send_event_with_timeoffset(index, source, sourcetype, json_data, event_timestamp) + send_event_with_time_offset(index, source, sourcetype, json_data, event_timestamp) search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source - logger.info(f"SPL: {search_query}") - events = check_events_from_splunk(start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format( - search_query)], - password=setup["splunk_password"]) - past_events = check_events_from_splunk(start_time="-30m@m", - end_time="-29m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format( - search_query)], - password=setup["splunk_password"]) - logger.info("Splunk received %s events in the last minute", - len(events)) + events = check_events_from_splunk( + start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format(search_query)], + password=setup["splunk_password"], + ) + past_events = check_events_from_splunk( + start_time="-30m@m", + end_time="-29m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format(search_query)], + password=setup["splunk_password"], + ) + logger.info("Splunk received %s events in the last minute", len(events)) + logger.info( + "Splunk received %s events in the selected timeframe (~30 mins ago)", + len(past_events), + ) assert len(events) == 0 assert len(past_events) >= 1 logger.info("Test Finished") # @pytest.mark.skip -@pytest.mark.parametrize("data,expected_event_count", [("This is the event!", 1), - ('{"test_name": "json_event","source": "file_log"}', 2)]) +@pytest.mark.parametrize( + "data,expected_event_count", + [ + ("This is the event!", 1), + ({"test_name": "json_event", "source": "file_log"}, 2), + ], +) def test_events_source_file_log_receiver_text(setup, data, expected_event_count): - ''' - What is this test doing - ''' - logger.info("Starting file log receiver test!") - logger.info("\n----------") - index = "file_logs" + """ + What is this test doing + - check events received via file log receiver + """ + logger.info(" -- Starting: file log receiver test! --") + index = config.EVENT_INDEX_FILE_LOG sourcetype = "filelog_sourcetype" search_query = "index=" + index + " sourcetype=" + sourcetype - logger.info(f"SPL: {search_query}") - events = check_events_from_splunk(start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format( - search_query)], - password=setup["splunk_password"]) - logger.info("Splunk received %s events in the last minute", - len(events)) + events = check_events_from_splunk( + start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format(search_query)], + password=setup["splunk_password"], + ) + logger.info("Splunk received %s events in the last minute", len(events)) assert len(events) == expected_event_count - 1 add_filelog_event(data) - events = check_events_from_splunk(start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format( - search_query)], - password=setup["splunk_password"]) - logger.info("Splunk received %s events in the last minute", - len(events)) + events = check_events_from_splunk( + start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + query=["search {0}".format(search_query)], + password=setup["splunk_password"], + ) + logger.info("Splunk received %s events in the last minute", len(events)) assert len(events) >= expected_event_count logger.info("Test Finished") # @pytest.mark.skip -@pytest.mark.parametrize("metric_name", [ - "system.filesystem.inodes.usage", - "system.filesystem.usage", - "system.memory.usage", - "system.network.connections", - "system.network.dropped", - "system.network.errors", - "system.network.io", - "system.network.packets", - "system.cpu.load_average.1m", - "system.cpu.load_average.5m", - "system.cpu.load_average.15m" - -]) -def test_splunk_hostmetric_events(setup, metric_name): - ''' - What is this test doing - ''' - logger.info("\n----------") - index = "metrics" - source = "source_test_2" - sourcetype = "sourcetype_test_2" - - send_metric(index, source, sourcetype) - events = check_metrics_from_splunk(start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - metric_name=metric_name, - index=index, - password=setup["splunk_password"]) - logger.info("Splunk received %s events in the last minute", - len(events)) +@pytest.mark.parametrize( + "metric_name", + [ + "system.filesystem.inodes.usage", + "system.filesystem.usage", + "system.memory.usage", + "system.network.connections", + "system.network.dropped", + "system.network.errors", + "system.network.io", + "system.network.packets", + "system.cpu.load_average.1m", + "system.cpu.load_average.5m", + "system.cpu.load_average.15m", + ], +) +def test_splunk_host_metric_events(setup, metric_name): + """ + What is this test doing + - host metrics receiver test + """ + logger.info("\n-- Starting: host metrics test! --") + index = config.METRICS_INDEX_HOST_METRICS + events = check_metrics_from_splunk( + start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + metric_name=metric_name, + index=index, + password=setup["splunk_password"], + ) + logger.info("Splunk received %s events in the last minute", len(events)) assert len(events) >= 1 logger.info("Test Finished") # @pytest.mark.skip def test_splunk_metric_events(setup): - ''' - What is this test doing - ''' - logger.info("\n----------") - index = "sck-metrics" + """ + What is this test doing + - check metrics via metrics endpoint test + """ + logger.info("\n-- Starting: check metrics via metrics endpoint test --") + index = config.METRICS_INDEX_METRICS_ENDPOINT source = "source_test_metric" sourcetype = "sourcetype_test_metric" send_metric(index, source, sourcetype) - events = check_metrics_from_splunk(start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - metric_name="test.metric", - index=index, - password=setup["splunk_password"]) - logger.info("Splunk received %s events in the last minute", - len(events)) + events = check_metrics_from_splunk( + start_time="-1m@m", + url=setup["splunkd_url"], + user=setup["splunk_user"], + metric_name="test.metric", + index=index, + password=setup["splunk_password"], + ) + logger.info("Splunk received %s events in the last minute", len(events)) assert len(events) >= 1 logger.info("Test Finished") diff --git a/exporter/splunkhecexporter/test/event_generator.py b/exporter/splunkhecexporter/test/event_generator.py index 10e1f296b6a7..67e571ec5a50 100644 --- a/exporter/splunkhecexporter/test/event_generator.py +++ b/exporter/splunkhecexporter/test/event_generator.py @@ -9,68 +9,57 @@ def wait_for_event_to_be_indexed_in_splunk(): time.sleep(3) -def send_event_old(): - print("sending event") - json_data = {"event": "Pony 8 has left the barn", "index": "main"} - requests.post("http://0.0.0.0:8883", json=json_data, verify=False) - wait_for_event_to_be_indexed_in_splunk() - - def send_event(index, source, source_type, data): - print("sending event") - json_data = {"event": data, - # "time": 1677241967.317544, - "index": index, - "host": "localhost", - "source": source, - "sourcetype": source_type, - } + print("Sending event") + json_data = { + "event": data, + "index": index, + "host": "localhost", + "source": source, + "sourcetype": source_type, + } requests.post("http://0.0.0.0:8883", json=json_data, verify=False) wait_for_event_to_be_indexed_in_splunk() -def send_event_with_timeoffset(index, source, source_type, data, time): - print("sending event") - json_data = {"event": data, - "time": time, - "index": index, - "host": "localhost", - "source": source, - "sourcetype": source_type, - } +def send_event_with_time_offset(index, source, source_type, data, time): + print("Sending event with time offset") + json_data = { + "event": data, + "time": time, + "index": index, + "host": "localhost", + "source": source, + "sourcetype": source_type, + } requests.post("http://0.0.0.0:8883", json=json_data, verify=False) wait_for_event_to_be_indexed_in_splunk() def send_metric(index, source, source_type): - print("sending metric") - fields_1 = {"metric_name:test.metric": 123, - "k0": "v0", - "k1": "v1"} - - fields_2 = {"region": "us-west-1", "datacenter": "dc1", "rack": "63", "os": "Ubuntu16.10", "arch": "x64", - "team": "LON", "service": "6", "service_version": "0", "service_environment": "test", - "path": "/dev/sda1", - "fstype": "ext3", "metric_name:cpu.usr": 11.12, "metric_name:cpu.sys": 12.23, - "metric_name:cpu.idle": 13.34} - + print("Sending metric event") + fields = { + "metric_name:test.metric": 123, + "k0": "v0", + "k1": "v1", + "metric_name:cpu.usr": 11.12, + "metric_name:cpu.sys": 12.23, + } json_data = { "host": "localhost", "source": source, "sourcetype": source_type, "index": index, "event": "metric", - "fields": fields_1 + "fields": fields, } requests.post("http://127.0.0.1:8884", json=json_data, verify=False) wait_for_event_to_be_indexed_in_splunk() def add_filelog_event(data): - print("adding file event") + print("Adding file event") f = open("./../../../bin/test_file.json", "a") - # f.write(data) - # f.close() for line in data: f.write(line) @@ -80,6 +69,6 @@ def add_filelog_event(data): # if __name__ == "__main__": - # send_event() - # send_metric() - # add_filelog_event() +# send_event() +# send_metric() +# add_filelog_event() From 8e8fc0dfca157c5f110c72e08ecd07c568f0866a Mon Sep 17 00:00:00 2001 From: Pawel Szkamruk Date: Wed, 1 Mar 2023 16:46:12 +0100 Subject: [PATCH 3/8] updating git ignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 9d39ea0b8bcc..3dd6fec63043 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,7 @@ integration-coverage.html # Wix *.wixobj *.wixpdb + +# python +.pytest_cache +__pycache__ \ No newline at end of file From a833a753edde75a600d46e2cc7389d33961bd2c5 Mon Sep 17 00:00:00 2001 From: Pawel Szkamruk Date: Thu, 2 Mar 2023 12:18:05 +0100 Subject: [PATCH 4/8] workflow to run e2e hec exporter tests --- .github/workflows/e2e-hec-exporter-tests.yaml | 87 +++++++++++++++++++ .../test/ci_scripts/k8s-splunk.yml | 31 +++++++ 2 files changed, 118 insertions(+) create mode 100644 .github/workflows/e2e-hec-exporter-tests.yaml create mode 100644 exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml diff --git a/.github/workflows/e2e-hec-exporter-tests.yaml b/.github/workflows/e2e-hec-exporter-tests.yaml new file mode 100644 index 000000000000..634c11ea10f2 --- /dev/null +++ b/.github/workflows/e2e-hec-exporter-tests.yaml @@ -0,0 +1,87 @@ +name: Splunk Platform Functional Test + +on: pull_request + +jobs: + e2e-test: + name: HEC Exporter e2e tests + runs-on: ubuntu-20.04 + + env: + CI_SPLUNK_PORT: 8089 + CI_SPLUNK_USERNAME: admin + CI_SPLUNK_HEC_TOKEN: a6b5e77f-d5f6-415a-bd43-930cecb12959 + CI_SPLUNK_PASSWORD: helloworld + CI_INDEX_EVENTS: ci_events + CI_INDEX_METRICS: ci_metrics + CONTAINER_RUNTIME: docker + KUBERNETES_VERSION: v1.21.2 + MINIKUBE_VERSION: v1.22.0 + + steps: + - name: Checkout + uses: actions/checkout@v3 + +# # Leave this here for debugging +# - name: Setup upterm session +# uses: lhotari/action-upterm@v1 + + - name: Setup Minikube + run: | + # Install Kubectl + curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/${KUBERNETES_VERSION}/bin/linux/amd64/kubectl + chmod +x kubectl + sudo mv kubectl /usr/local/bin/ + mkdir -p ${HOME}/.kube + touch ${HOME}/.kube/config + # Install Minikube + curl -Lo minikube https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64 + chmod +x minikube + sudo mv minikube /usr/local/bin/ + sudo sysctl fs.protected_regular=0 + # Start Minikube and Wait + minikube start --container-runtime=${CONTAINER_RUNTIME} --cpus 2 --memory 4096 --kubernetes-version=${KUBERNETES_VERSION} --no-vtx-check + kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml + export JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' + until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do + sleep 1; + done + - name: Install Splunk + run: | + # Wait until default service account is created + until kubectl -n default get serviceaccount default -o name; do + sleep 1; + done + # Install Splunk on minikube + kubectl apply -f exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml + # Wait until splunk is ready + until kubectl logs splunk --tail=2 | grep -q 'Ansible playbook complete'; do + sleep 1; + done + export CI_SPLUNK_HOST=$(kubectl get pod splunk --template={{.status.podIP}}) + # Setup Indexes + curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=$CI_INDEX_EVENTS -d datatype=event + curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=ns-anno -d datatype=event + curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=pod-anno -d datatype=event + curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=$CI_INDEX_METRICS -d datatype=metric + # Enable HEC services + curl -X POST -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD -k https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/servicesNS/nobody/splunk_httpinput/data/inputs/http/http/enable + # Create new HEC token + curl -X POST -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD -k -d "name=splunk_hec_token&token=a6b5e77f-d5f6-415a-bd43-930cecb12959&disabled=0&index=main&indexes=main,ci_events,ci_metrics,ns-anno,pod-anno" https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/servicesNS/nobody/splunk_httpinput/data/inputs/http + # Restart Splunk + curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/server/control/restart -X POST + + - name: Run functional tests + run: | + kubectl get nodes + export PYTHONWARNINGS="ignore:Unverified HTTPS request" + export CI_SPLUNK_HOST=$(kubectl get pod splunk --template={{.status.podIP}}) + cd exporter/splunkhecexporter/test + pip install --upgrade pip + pip install -r requirements.txt + echo "Running functional tests....." + python -m pytest \ + --splunkd-url https://$CI_SPLUNK_HOST:8089 \ + --splunk-user admin \ + --splunk-password $CI_SPLUNK_PASSWORD \ + -p no:warnings -s \ No newline at end of file diff --git a/exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml b/exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml new file mode 100644 index 000000000000..9f6328a94a80 --- /dev/null +++ b/exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + name: splunk +spec: + hostNetwork: true + securityContext: + runAsUser: 0 + runAsGroup: 0 + containers: + - name: splunk + image: splunk/splunk:8.2.0 + ports: + - containerPort: 8000 + hostPort: 8000 + protocol: TCP + - containerPort: 8088 + hostPort: 8088 + protocol: TCP + - containerPort: 8089 + hostPort: 8089 + protocol: TCP + env: + - name: SPLUNK_START_ARGS + value: --accept-license + - name: SPLUNK_USER + value: root + - name: SPLUNK_PASSWORD + value: helloworld + - name: SPLUNK_LAUNCH_CONF + value: OPTIMISTIC_ABOUT_FILE_LOCKING=1 \ No newline at end of file From 30010353c108a0d1072c19f68597fec0ac88e9a4 Mon Sep 17 00:00:00 2001 From: Pawel Szkamruk Date: Thu, 2 Mar 2023 12:26:47 +0100 Subject: [PATCH 5/8] pipeline - 1 --- .github/workflows/e2e-hec-exporter-tests.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-hec-exporter-tests.yaml b/.github/workflows/e2e-hec-exporter-tests.yaml index 634c11ea10f2..894a07591a3d 100644 --- a/.github/workflows/e2e-hec-exporter-tests.yaml +++ b/.github/workflows/e2e-hec-exporter-tests.yaml @@ -1,6 +1,7 @@ -name: Splunk Platform Functional Test +name: e2e-hec-exporter-tests -on: pull_request +on: + workflow_dispatch: jobs: e2e-test: From 20c4594b4b1adbd968030ce4dd0881603d679f5b Mon Sep 17 00:00:00 2001 From: pszkamruk-splunk <75434853+pszkamruk-splunk@users.noreply.github.com> Date: Wed, 22 Mar 2023 16:04:27 +0100 Subject: [PATCH 6/8] Revert "Hec exporter tests" (#5) --- .github/workflows/e2e-hec-exporter-tests.yaml | 88 ------ .gitignore | 4 - exporter/splunkhecexporter/test/__init__.py | 0 .../test/ci_scripts/k8s-splunk.yml | 31 -- exporter/splunkhecexporter/test/common.py | 292 ------------------ .../splunkhecexporter/test/config/config.yaml | 57 ---- .../test/config/config_data.py | 6 - exporter/splunkhecexporter/test/conftest.py | 64 ---- .../test/e2e_tests/__init__.py | 0 .../e2e_tests/test_hec_exporter_positive.py | 223 ------------- .../splunkhecexporter/test/event_generator.py | 74 ----- exporter/splunkhecexporter/test/pytest.ini | 3 - .../splunkhecexporter/test/requirements.txt | 2 - 13 files changed, 844 deletions(-) delete mode 100644 .github/workflows/e2e-hec-exporter-tests.yaml delete mode 100644 exporter/splunkhecexporter/test/__init__.py delete mode 100644 exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml delete mode 100644 exporter/splunkhecexporter/test/common.py delete mode 100644 exporter/splunkhecexporter/test/config/config.yaml delete mode 100644 exporter/splunkhecexporter/test/config/config_data.py delete mode 100644 exporter/splunkhecexporter/test/conftest.py delete mode 100644 exporter/splunkhecexporter/test/e2e_tests/__init__.py delete mode 100644 exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py delete mode 100644 exporter/splunkhecexporter/test/event_generator.py delete mode 100644 exporter/splunkhecexporter/test/pytest.ini delete mode 100644 exporter/splunkhecexporter/test/requirements.txt diff --git a/.github/workflows/e2e-hec-exporter-tests.yaml b/.github/workflows/e2e-hec-exporter-tests.yaml deleted file mode 100644 index 894a07591a3d..000000000000 --- a/.github/workflows/e2e-hec-exporter-tests.yaml +++ /dev/null @@ -1,88 +0,0 @@ -name: e2e-hec-exporter-tests - -on: - workflow_dispatch: - -jobs: - e2e-test: - name: HEC Exporter e2e tests - runs-on: ubuntu-20.04 - - env: - CI_SPLUNK_PORT: 8089 - CI_SPLUNK_USERNAME: admin - CI_SPLUNK_HEC_TOKEN: a6b5e77f-d5f6-415a-bd43-930cecb12959 - CI_SPLUNK_PASSWORD: helloworld - CI_INDEX_EVENTS: ci_events - CI_INDEX_METRICS: ci_metrics - CONTAINER_RUNTIME: docker - KUBERNETES_VERSION: v1.21.2 - MINIKUBE_VERSION: v1.22.0 - - steps: - - name: Checkout - uses: actions/checkout@v3 - -# # Leave this here for debugging -# - name: Setup upterm session -# uses: lhotari/action-upterm@v1 - - - name: Setup Minikube - run: | - # Install Kubectl - curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/${KUBERNETES_VERSION}/bin/linux/amd64/kubectl - chmod +x kubectl - sudo mv kubectl /usr/local/bin/ - mkdir -p ${HOME}/.kube - touch ${HOME}/.kube/config - # Install Minikube - curl -Lo minikube https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64 - chmod +x minikube - sudo mv minikube /usr/local/bin/ - sudo sysctl fs.protected_regular=0 - # Start Minikube and Wait - minikube start --container-runtime=${CONTAINER_RUNTIME} --cpus 2 --memory 4096 --kubernetes-version=${KUBERNETES_VERSION} --no-vtx-check - kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml - export JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' - until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do - sleep 1; - done - - name: Install Splunk - run: | - # Wait until default service account is created - until kubectl -n default get serviceaccount default -o name; do - sleep 1; - done - # Install Splunk on minikube - kubectl apply -f exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml - # Wait until splunk is ready - until kubectl logs splunk --tail=2 | grep -q 'Ansible playbook complete'; do - sleep 1; - done - export CI_SPLUNK_HOST=$(kubectl get pod splunk --template={{.status.podIP}}) - # Setup Indexes - curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=$CI_INDEX_EVENTS -d datatype=event - curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=ns-anno -d datatype=event - curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=pod-anno -d datatype=event - curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/data/indexes -d name=$CI_INDEX_METRICS -d datatype=metric - # Enable HEC services - curl -X POST -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD -k https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/servicesNS/nobody/splunk_httpinput/data/inputs/http/http/enable - # Create new HEC token - curl -X POST -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD -k -d "name=splunk_hec_token&token=a6b5e77f-d5f6-415a-bd43-930cecb12959&disabled=0&index=main&indexes=main,ci_events,ci_metrics,ns-anno,pod-anno" https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/servicesNS/nobody/splunk_httpinput/data/inputs/http - # Restart Splunk - curl -k -u $CI_SPLUNK_USERNAME:$CI_SPLUNK_PASSWORD https://$CI_SPLUNK_HOST:$CI_SPLUNK_PORT/services/server/control/restart -X POST - - - name: Run functional tests - run: | - kubectl get nodes - export PYTHONWARNINGS="ignore:Unverified HTTPS request" - export CI_SPLUNK_HOST=$(kubectl get pod splunk --template={{.status.podIP}}) - cd exporter/splunkhecexporter/test - pip install --upgrade pip - pip install -r requirements.txt - echo "Running functional tests....." - python -m pytest \ - --splunkd-url https://$CI_SPLUNK_HOST:8089 \ - --splunk-user admin \ - --splunk-password $CI_SPLUNK_PASSWORD \ - -p no:warnings -s \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3dd6fec63043..9d39ea0b8bcc 100644 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,3 @@ integration-coverage.html # Wix *.wixobj *.wixpdb - -# python -.pytest_cache -__pycache__ \ No newline at end of file diff --git a/exporter/splunkhecexporter/test/__init__.py b/exporter/splunkhecexporter/test/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml b/exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml deleted file mode 100644 index 9f6328a94a80..000000000000 --- a/exporter/splunkhecexporter/test/ci_scripts/k8s-splunk.yml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: splunk -spec: - hostNetwork: true - securityContext: - runAsUser: 0 - runAsGroup: 0 - containers: - - name: splunk - image: splunk/splunk:8.2.0 - ports: - - containerPort: 8000 - hostPort: 8000 - protocol: TCP - - containerPort: 8088 - hostPort: 8088 - protocol: TCP - - containerPort: 8089 - hostPort: 8089 - protocol: TCP - env: - - name: SPLUNK_START_ARGS - value: --accept-license - - name: SPLUNK_USER - value: root - - name: SPLUNK_PASSWORD - value: helloworld - - name: SPLUNK_LAUNCH_CONF - value: OPTIMISTIC_ABOUT_FILE_LOCKING=1 \ No newline at end of file diff --git a/exporter/splunkhecexporter/test/common.py b/exporter/splunkhecexporter/test/common.py deleted file mode 100644 index f60eed498265..000000000000 --- a/exporter/splunkhecexporter/test/common.py +++ /dev/null @@ -1,292 +0,0 @@ -""" -Copyright 2018-2019 Splunk, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import json -import logging -import time -import requests -import os -import sys -from requests.packages.urllib3.util.retry import Retry -from requests.adapters import HTTPAdapter - - -TIMEROUT = 500 - -logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) -formatter = logging.Formatter( - "%(asctime)s - %(name)s -" + " %(levelname)s - %(message)s" -) -handler = logging.StreamHandler(sys.stdout) -handler.setFormatter(formatter) -logger.addHandler(handler) - - -def check_events_from_splunk( - start_time="-1h@h", - end_time="now", - url="", - user="", - query="", - password="", -): - """ - send a search request to splunk and return the events from the result - """ - logger.info("search query = " + str(query)) - events = _collect_events(query, start_time, end_time, url, user, password) - - return events - - -def check_metrics_from_splunk( - index="metrics", - start_time="-1h@h", - end_time="now", - url="", - user="", - password="", - metric_name="", -): - """ - send a search api request to splunk to check for values associated with a given metric and dimension - """ - logger.debug("Calling _collect_metrics ") - events = _collect_metrics( - start_time, end_time, url, user, password, index, metric_name - ) - - return events - - -def create_index_in_splunk(index="", url="", user="", password=""): - """ - Send a request to a Splunk instance to create an index - @param: index (index to be deleted) - @param: url (splunkd rest api url) - @param: user (splunk username) - @param: password (splunk password) - returns True/False - """ - - search_url = "{0}/services/data/indexes/{1}?output_mode=json".format(url, index) - logger.debug("requesting: %s", search_url) - data = {"name": index} - - create_job = _requests_retry_session().post( - search_url, auth=(user, password), verify=False, data=data - ) - - if create_job.status_code == 201: - logger.info("The index: %s successfully created", index) - elif create_job.status_code == 409: - logger.info("The index: %s already exits", index) - else: - logger.info( - "The index: {0} not created, exit code is {1}".format( - index, create_job.status_code - ) - ) - return False - - return True - - -def delete_index_in_splunk(index="", user="", url="", password=""): - """ - Send a request to a Splunk instance to delete an index - @param: index (index to be deleted) - @param: url (splunkd rest api url) - @param: user (splunk username) - @param: password (splunk password) - returns True/False - """ - - search_url = "{0}/services/data/indexes/{1}?output_mode=json".format(url, index) - logger.debug("requesting: %s", search_url) - data = {"name": index} - - create_job = _requests_retry_session().delete( - search_url, auth=(user, password), verify=False, data=data - ) - - if create_job.status_code == 200: - logger.info("The index: %s successfully deleted", index) - elif create_job.status_code == 409: - logger.info("The index: %s already disabled", index) - else: - return False - - return True - - -def _collect_events(query, start_time, end_time, url="", user="", password=""): - """ - Collect events by running the given search query - @param: query (search query) - @param: start_time (search start time) - @param: end_time (search end time) - returns events - """ - - search_url = "{0}/services/search/jobs?output_mode=json".format(url) - logger.debug("requesting: %s", search_url) - data = { - "search": query, - "earliest_time": start_time, - "latest_time": end_time, - } - - create_job = _requests_retry_session().post( - search_url, auth=(user, password), verify=False, data=data - ) - _check_request_status(create_job) - - json_res = create_job.json() - job_id = json_res["sid"] - events = _wait_for_job_and__get_events(job_id, url, user, password) - - return events - - -def _collect_metrics( - start_time, end_time, url="", user="", password="", index="", metric_name="" -): - """ - Verify metrics by running the given api query - @param: dimension (metric dimension) - @param: metric_name (metric name) - @param: start_time (search start time) - @param: end_time (search end time) - returns events - """ - api_url = ( - url - + "/services/catalog/metricstore/dimensions/host/values?filter=index%3d" - + index - + "&metric_name=" - + metric_name - + "&earliest=" - + start_time - + "&latest=" - + end_time - + "&output_mode=json".format(url) - ) - logger.debug("requesting: %s", api_url) - - create_job = _requests_retry_session().get( - api_url, auth=(user, password), verify=False - ) - - _check_request_status(create_job) - - json_res = create_job.json() - - events = json_res["entry"] - # logger.info('events: %s', events) - - return events - - -def _wait_for_job_and__get_events(job_id, url="", user="", password=""): - """ - Wait for the search job to finish and collect the result events - @param: job_id - returns events - """ - events = [] - job_url = "{0}/services/search/jobs/{1}?output_mode=json".format(url, str(job_id)) - logger.debug("requesting: %s", job_url) - - for _ in range(TIMEROUT): - res = _requests_retry_session().get( - job_url, auth=(user, password), verify=False - ) - _check_request_status(res) - - job_res = res.json() - dispatch_state = job_res["entry"][0]["content"]["dispatchState"] - - if dispatch_state == "DONE": - events = _get_events(job_id, url, user, password) - break - if dispatch_state == "FAILED": - raise Exception("Search job: {0} failed".format(job_url)) - time.sleep(1) - - return events - - -def _get_events(job_id, url="", user="", password=""): - """ - collect the result events from a search job - @param: job_id - returns events - """ - event_url = "{0}/services/search/jobs/{1}/events?output_mode=json".format( - url, str(job_id) - ) - logger.debug("requesting: %s", event_url) - - event_job = _requests_retry_session().get( - event_url, auth=(user, password), verify=False - ) - _check_request_status(event_job) - - event_job_json = event_job.json() - events = event_job_json["results"] - logger.debug("Events from get_events method returned %s events", len(events)) - - return events - - -def _check_request_status(req_obj): - """ - check if a request is successful - @param: req_obj - returns True/False - """ - if not req_obj.ok: - raise Exception( - "status code: {0} \n details: {1}".format( - str(req_obj.status_code), req_obj.text - ) - ) - - -def _requests_retry_session( - retries=10, backoff_factor=0.1, status_forcelist=(500, 502, 504) -): - """ - create a retry session for HTTP/HTTPS requests - @param: retries (num of retry time) - @param: backoff_factor - @param: status_forcelist (list of error status code to trigger retry) - @param: session - returns: session - """ - session = requests.Session() - retry = Retry( - total=int(retries), - backoff_factor=backoff_factor, - status_forcelist=status_forcelist, - ) - adapter = HTTPAdapter(max_retries=retry) - session.mount("http://", adapter) - session.mount("https://", adapter) - - return session diff --git a/exporter/splunkhecexporter/test/config/config.yaml b/exporter/splunkhecexporter/test/config/config.yaml deleted file mode 100644 index bb781fc55908..000000000000 --- a/exporter/splunkhecexporter/test/config/config.yaml +++ /dev/null @@ -1,57 +0,0 @@ -receivers: - filelog: - include: [ ./*.json ] - splunk_hec/logs: - endpoint: 0.0.0.0:8883 - splunk_hec/metrics: - endpoint: 0.0.0.0:8884 - hostmetrics: - collection_interval: 30s - scrapers: - cpu: - disk: - load: - filesystem: - memory: - network: -exporters: - splunk_hec: - # Splunk HTTP Event Collector token. - token: "00000000-0000-0000-0000-000000000000" - # URL to a Splunk instance to send data to. - endpoint: "https://10.202.11.213:8088/services/collector" - index: "metrics" - health_path: "/services/collector/health" - health_check_enabled: true - tls: - insecure_skip_verify: true - splunk_hec/logs: - # Splunk HTTP Event Collector token. - token: "00000000-0000-0000-0000-000000000000" - # URL to a Splunk instance to send data to. - endpoint: "https://10.202.11.213:8088/services/collector" - sourcetype: "filelog_sourcetype" - index: "file_logs" - health_path: "/services/collector/health" - health_check_enabled: true - tls: - insecure_skip_verify: true - logging: - loglevel: debug -service: - telemetry: - logs: - level: "debug" - pipelines: - metrics: - receivers: [splunk_hec/metrics] - exporters: [splunk_hec, logging] - metrics/2: - receivers: [hostmetrics] - exporters: [splunk_hec, logging] - logs: - receivers: [splunk_hec/logs] - exporters: [splunk_hec, logging] - logs/2: - receivers: [ filelog ] - exporters: [ splunk_hec/logs, logging ] diff --git a/exporter/splunkhecexporter/test/config/config_data.py b/exporter/splunkhecexporter/test/config/config_data.py deleted file mode 100644 index 633cb6819563..000000000000 --- a/exporter/splunkhecexporter/test/config/config_data.py +++ /dev/null @@ -1,6 +0,0 @@ -# indexes -EVENT_INDEX_1 = "main" -EVENT_INDEX_2 = "sck-otel" -EVENT_INDEX_FILE_LOG = "file_logs" -METRICS_INDEX_HOST_METRICS = "metrics" -METRICS_INDEX_METRICS_ENDPOINT = "sck-metrics" diff --git a/exporter/splunkhecexporter/test/conftest.py b/exporter/splunkhecexporter/test/conftest.py deleted file mode 100644 index 1a2c0cfd9022..000000000000 --- a/exporter/splunkhecexporter/test/conftest.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -Copyright 2018-2019 Splunk, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import pytest -import config.config_data as config_data -from common import check_events_from_splunk - - -def pytest_addoption(parser): - parser.addoption( - "--splunkd-url", - help="splunkd url used to send test data to. \ - Eg: https://localhost:8089", - default="https://localhost:8089", - ) - parser.addoption("--splunk-user", help="splunk username", default="admin") - parser.addoption( - "--splunk-password", help="splunk user password", default="password" - ) - - -# Print events ingested in splunk for debugging -def pytest_unconfigure(config): - indexes = [ - config_data.EVENT_INDEX_1, - config_data.EVENT_INDEX_2, - config_data.EVENT_INDEX_FILE_LOG, - ] - for index in indexes: - search_query = "index=" + index + " | fields *" - events = check_events_from_splunk( - start_time="-1h@h", - url=config.getoption("--splunkd-url"), - user=config.getoption("--splunk-user"), - query=["search {0}".format(search_query)], - password=config.getoption("--splunk-password"), - ) - print("index=" + index + " event count=" + str(len(events))) - # debug print all events - # for event in events: - # print(event) - - -@pytest.fixture(scope="function") -def setup(request): - config = {} - config["splunkd_url"] = request.config.getoption("--splunkd-url") - config["splunk_user"] = request.config.getoption("--splunk-user") - config["splunk_password"] = request.config.getoption("--splunk-password") - - return config diff --git a/exporter/splunkhecexporter/test/e2e_tests/__init__.py b/exporter/splunkhecexporter/test/e2e_tests/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py b/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py deleted file mode 100644 index b779b085d801..000000000000 --- a/exporter/splunkhecexporter/test/e2e_tests/test_hec_exporter_positive.py +++ /dev/null @@ -1,223 +0,0 @@ -import time - -import pytest -import logging -import sys -import config.config_data as config -from ..event_generator import ( - send_event, - send_metric, - send_event_with_time_offset, - add_filelog_event, -) -from ..common import check_events_from_splunk, check_metrics_from_splunk - -logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) -formatter = logging.Formatter("%(message)s") -handler = logging.StreamHandler(sys.stdout) -handler.setFormatter(formatter) -logger.addHandler(handler) - - -# @pytest.mark.skip -@pytest.mark.parametrize("test_data,expected", [("test_data", 1)]) -def test_splunk_event_metadata_as_string(setup, test_data, expected): - """ - What is this test doing - - check text event received via event endpoint - """ - logger.info("-- Starting: check text event received via event endpoint --") - index = config.EVENT_INDEX_1 - source = "source_test_1" - sourcetype = "sourcetype_test_1" - send_event(index, source, sourcetype, test_data) - search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source - events = check_events_from_splunk( - start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format(search_query)], - password=setup["splunk_password"], - ) - logger.info("Splunk received %s events in the last minute", len(events)) - assert len(events) >= expected - - logger.info("Test Finished") - - -# @pytest.mark.skip -def test_splunk_event_json_object(setup): - """ - What is this test doing - - check json event received via event endpoint - """ - logger.info("-- Starting: check json event received via event endpoint --") - index = config.EVENT_INDEX_2 - source = "source_test_2" - sourcetype = "sourcetype_test_2" - json_data = { - "test_name": "Test 2b timestamp", - "field1": "test", - "field2": 155, - "index": index, - } - - send_event(index, source, sourcetype, json_data) - search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source - events = check_events_from_splunk( - start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format(search_query)], - password=setup["splunk_password"], - ) - logger.info("Splunk received %s events in the last minute", len(events)) - assert len(events) >= 1 - logger.info("Test Finished") - - -# @pytest.mark.skip -def test_splunk_event_timestamp(setup): - """ - What is this test doing - - check event timestamp test - """ - logger.info("-- Starting: check event timestamp test --") - index = config.EVENT_INDEX_2 - source = "source_test_3" - sourcetype = "sourcetype_test_3" - event_timestamp = time.time() - 1800 - json_data = { - "time": event_timestamp, - "test_name": "Test timestamp", - "index": index, - } - send_event_with_time_offset(index, source, sourcetype, json_data, event_timestamp) - search_query = "index=" + index + " sourcetype=" + sourcetype + " source=" + source - events = check_events_from_splunk( - start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format(search_query)], - password=setup["splunk_password"], - ) - past_events = check_events_from_splunk( - start_time="-30m@m", - end_time="-29m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format(search_query)], - password=setup["splunk_password"], - ) - logger.info("Splunk received %s events in the last minute", len(events)) - logger.info( - "Splunk received %s events in the selected timeframe (~30 mins ago)", - len(past_events), - ) - assert len(events) == 0 - assert len(past_events) >= 1 - logger.info("Test Finished") - - -# @pytest.mark.skip -@pytest.mark.parametrize( - "data,expected_event_count", - [ - ("This is the event!", 1), - ({"test_name": "json_event", "source": "file_log"}, 2), - ], -) -def test_events_source_file_log_receiver_text(setup, data, expected_event_count): - """ - What is this test doing - - check events received via file log receiver - """ - logger.info(" -- Starting: file log receiver test! --") - index = config.EVENT_INDEX_FILE_LOG - sourcetype = "filelog_sourcetype" - - search_query = "index=" + index + " sourcetype=" + sourcetype - events = check_events_from_splunk( - start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format(search_query)], - password=setup["splunk_password"], - ) - logger.info("Splunk received %s events in the last minute", len(events)) - assert len(events) == expected_event_count - 1 - add_filelog_event(data) - - events = check_events_from_splunk( - start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - query=["search {0}".format(search_query)], - password=setup["splunk_password"], - ) - logger.info("Splunk received %s events in the last minute", len(events)) - assert len(events) >= expected_event_count - logger.info("Test Finished") - - -# @pytest.mark.skip -@pytest.mark.parametrize( - "metric_name", - [ - "system.filesystem.inodes.usage", - "system.filesystem.usage", - "system.memory.usage", - "system.network.connections", - "system.network.dropped", - "system.network.errors", - "system.network.io", - "system.network.packets", - "system.cpu.load_average.1m", - "system.cpu.load_average.5m", - "system.cpu.load_average.15m", - ], -) -def test_splunk_host_metric_events(setup, metric_name): - """ - What is this test doing - - host metrics receiver test - """ - logger.info("\n-- Starting: host metrics test! --") - index = config.METRICS_INDEX_HOST_METRICS - events = check_metrics_from_splunk( - start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - metric_name=metric_name, - index=index, - password=setup["splunk_password"], - ) - logger.info("Splunk received %s events in the last minute", len(events)) - assert len(events) >= 1 - logger.info("Test Finished") - - -# @pytest.mark.skip -def test_splunk_metric_events(setup): - """ - What is this test doing - - check metrics via metrics endpoint test - """ - logger.info("\n-- Starting: check metrics via metrics endpoint test --") - index = config.METRICS_INDEX_METRICS_ENDPOINT - source = "source_test_metric" - sourcetype = "sourcetype_test_metric" - - send_metric(index, source, sourcetype) - events = check_metrics_from_splunk( - start_time="-1m@m", - url=setup["splunkd_url"], - user=setup["splunk_user"], - metric_name="test.metric", - index=index, - password=setup["splunk_password"], - ) - logger.info("Splunk received %s events in the last minute", len(events)) - assert len(events) >= 1 - logger.info("Test Finished") diff --git a/exporter/splunkhecexporter/test/event_generator.py b/exporter/splunkhecexporter/test/event_generator.py deleted file mode 100644 index 67e571ec5a50..000000000000 --- a/exporter/splunkhecexporter/test/event_generator.py +++ /dev/null @@ -1,74 +0,0 @@ -import logging -import time - -import requests - - -def wait_for_event_to_be_indexed_in_splunk(): - logging.info("Wating for event indexing") - time.sleep(3) - - -def send_event(index, source, source_type, data): - print("Sending event") - json_data = { - "event": data, - "index": index, - "host": "localhost", - "source": source, - "sourcetype": source_type, - } - requests.post("http://0.0.0.0:8883", json=json_data, verify=False) - wait_for_event_to_be_indexed_in_splunk() - - -def send_event_with_time_offset(index, source, source_type, data, time): - print("Sending event with time offset") - json_data = { - "event": data, - "time": time, - "index": index, - "host": "localhost", - "source": source, - "sourcetype": source_type, - } - requests.post("http://0.0.0.0:8883", json=json_data, verify=False) - wait_for_event_to_be_indexed_in_splunk() - - -def send_metric(index, source, source_type): - print("Sending metric event") - fields = { - "metric_name:test.metric": 123, - "k0": "v0", - "k1": "v1", - "metric_name:cpu.usr": 11.12, - "metric_name:cpu.sys": 12.23, - } - json_data = { - "host": "localhost", - "source": source, - "sourcetype": source_type, - "index": index, - "event": "metric", - "fields": fields, - } - requests.post("http://127.0.0.1:8884", json=json_data, verify=False) - wait_for_event_to_be_indexed_in_splunk() - - -def add_filelog_event(data): - print("Adding file event") - f = open("./../../../bin/test_file.json", "a") - - for line in data: - f.write(line) - f.write("\n") - f.close() - wait_for_event_to_be_indexed_in_splunk() - - -# if __name__ == "__main__": -# send_event() -# send_metric() -# add_filelog_event() diff --git a/exporter/splunkhecexporter/test/pytest.ini b/exporter/splunkhecexporter/test/pytest.ini deleted file mode 100644 index f31b9cd5ccf3..000000000000 --- a/exporter/splunkhecexporter/test/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -addopts = -rfps --disable-pytest-warnings --continue-on-collection-errors --log-level=DEBUG -vv - diff --git a/exporter/splunkhecexporter/test/requirements.txt b/exporter/splunkhecexporter/test/requirements.txt deleted file mode 100644 index 16d3b778913e..000000000000 --- a/exporter/splunkhecexporter/test/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pytest -requests \ No newline at end of file From ec83dc04542405ca44d232af408b0d4e8f8232d7 Mon Sep 17 00:00:00 2001 From: Pawel Szkamruk Date: Tue, 13 Jun 2023 15:56:36 +0200 Subject: [PATCH 7/8] parent e601d8b6f135cc40df9580a91b4a61ef1d8492c5 author Pawel Szkamruk 1686664596 +0200 committer Pawel Szkamruk 1697787968 +0200 gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEiLgqjUke5gZqdUhD8uKMOu/hMOoFAmUyMEAACgkQ8uKMOu/h MOpIhhAA0PgvHe7VbY163Va6Y/fhy7kFNmAP+i/OajYWiB3XYl5ROkNhMV2DPERS ZcpQ7/NnzzJsZyWoCqjZbNAKpSg/DflUStwGp37/zlQFxLFTU8EKdx9t1RivmI0S fH98323SZXDBEnyxZeOt6yTxBES/SpIExqwx9K0TmN16Ab96tYtwPSz9OC+N0Vlg iLMaJMupILFpE+KoP4gnaR7kFSn7BDx68LXbRqMveSipBKpiUT0r4C28uZgnLjRM vXBHVTujXkOf16R2I3pu2u//iDIt1tHkoi3W2yAgyQDFnuUVZr4k/9mayOaB0l0x qJKB9NjV8UoIOYS95dSNyA0RuwEWlfktb4vDcx//FMiMfSC0rTms5agyF47wyDMl zJpGXDzvFLS5hJ/NMqzMchGt4XI6AHheskRWzrk1b4j18oUUPcI30QBQKU1sb3Ma j/kezz4GTw1VdpUXkXC9PgvuTpXDI7+gFJzgSnfPRDw2vQEUQCbtQ2+/1+F8BqLB fbnjnrmhLfpuTDzYSNsaMk4AbVItoiSGLUdVMhyQmouwpXQXoamw1B5AA0u0HqLM nnsViOpCY5htDiVQ+icEBjIhf8yKCbGtquVGBUk1dqVBXC6uKDyYWGj4iqSv0nMC vT1Qf1JWaEO6ELMFKPj35TvnNUfdY5aoO7tt8WKseJZFBLZtzDs= =YHOz -----END PGP SIGNATURE----- Splunk HEC exporter integration tests --- cmd/oteltestbedcol/go.sum | 9 + exporter/splunkhecexporter/go.mod | 35 +- exporter/splunkhecexporter/go.sum | 122 ++++++ .../splunkhecexporter/integration_test.go | 400 ++++++++++++++++++ .../integrationtestutils/config_helper.go | 113 +++++ .../internal/integrationtestutils/splunk.go | 227 ++++++++++ .../testdata/integration_tests_config.yaml | 20 + .../dockerobserver/integration_test.go | 5 - receiver/splunkhecreceiver/go.sum | 33 ++ 9 files changed, 958 insertions(+), 6 deletions(-) create mode 100644 exporter/splunkhecexporter/integration_test.go create mode 100644 exporter/splunkhecexporter/internal/integrationtestutils/config_helper.go create mode 100644 exporter/splunkhecexporter/internal/integrationtestutils/splunk.go create mode 100644 exporter/splunkhecexporter/testdata/integration_tests_config.yaml diff --git a/cmd/oteltestbedcol/go.sum b/cmd/oteltestbedcol/go.sum index 7ab46543da60..03ca44855b99 100644 --- a/cmd/oteltestbedcol/go.sum +++ b/cmd/oteltestbedcol/go.sum @@ -544,6 +544,7 @@ cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= @@ -585,6 +586,7 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= @@ -658,6 +660,8 @@ github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -1037,6 +1041,8 @@ github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmL github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -1064,6 +1070,7 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= @@ -1166,6 +1173,7 @@ github.com/signalfx/sapm-proto v0.13.0/go.mod h1:C72HjeCW5v0Llk6pIVJ/ZH8A5GbiZpC github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1200,6 +1208,7 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/testcontainers/testcontainers-go v0.25.0 h1:erH6cQjsaJrH+rJDU9qIf89KFdhK0Bft0aEZHlYC3Vs= github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= diff --git a/exporter/splunkhecexporter/go.mod b/exporter/splunkhecexporter/go.mod index 7b405c97362e..8da2370d007c 100644 --- a/exporter/splunkhecexporter/go.mod +++ b/exporter/splunkhecexporter/go.mod @@ -10,6 +10,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.87.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.87.0 github.com/stretchr/testify v1.8.4 + github.com/testcontainers/testcontainers-go v0.25.0 go.opencensus.io v0.24.0 go.opentelemetry.io/collector/component v0.87.1-0.20231017160804-ec0725874313 go.opentelemetry.io/collector/config/confighttp v0.87.1-0.20231017160804-ec0725874313 @@ -22,30 +23,60 @@ require ( go.opentelemetry.io/collector/semconv v0.87.1-0.20231017160804-ec0725874313 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/containerd/containerd v1.7.6 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.6+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/klauspost/compress v1.17.1 // indirect github.com/knadh/koanf/maps v0.1.1 // indirect github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.0.1 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/patternmatcher v0.5.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.87.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/runc v1.1.5 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/rs/cors v1.10.1 // indirect + github.com/shirou/gopsutil/v3 v3.23.9 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect go.opentelemetry.io/collector v0.87.1-0.20231017160804-ec0725874313 // indirect go.opentelemetry.io/collector/config/configauth v0.87.1-0.20231017160804-ec0725874313 // indirect go.opentelemetry.io/collector/config/configcompression v0.87.1-0.20231017160804-ec0725874313 // indirect @@ -58,13 +89,15 @@ require ( go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect + golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/grpc v1.58.3 // indirect google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal diff --git a/exporter/splunkhecexporter/go.sum b/exporter/splunkhecexporter/go.sum index db0739410992..881216976ef5 100644 --- a/exporter/splunkhecexporter/go.sum +++ b/exporter/splunkhecexporter/go.sum @@ -1,23 +1,53 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= +github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= +github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= +github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= @@ -27,6 +57,10 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -53,10 +87,15 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -69,8 +108,15 @@ github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPgh github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g= github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -78,13 +124,35 @@ github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmL github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= @@ -94,17 +162,43 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= +github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/testcontainers/testcontainers-go v0.25.0 h1:erH6cQjsaJrH+rJDU9qIf89KFdhK0Bft0aEZHlYC3Vs= +github.com/testcontainers/testcontainers-go v0.25.0/go.mod h1:4sC9SiJyzD1XFi59q8umTQYWxnkweEc5OjVtTUlJzqQ= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/collector v0.87.1-0.20231017160804-ec0725874313 h1:20fAuaqh24+cyQbkCErALoRjYdCfnV4wTWgDcZoOao8= @@ -161,11 +255,15 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 h1:FqrVOBQxQ8r/UwwXibI0KMolVhvFiGobSfdE33deHJM= +golang.org/x/exp v0.0.0-20230711023510-fffb14384f22/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -175,6 +273,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -183,17 +282,35 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -202,6 +319,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -231,13 +350,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/exporter/splunkhecexporter/integration_test.go b/exporter/splunkhecexporter/integration_test.go new file mode 100644 index 000000000000..766ea5b7f645 --- /dev/null +++ b/exporter/splunkhecexporter/integration_test.go @@ -0,0 +1,400 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:build integration + +package splunkhecexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/splunkhecexporter" + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + "os" + "os/exec" + "strconv" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configopaque" + "go.opentelemetry.io/collector/exporter/exportertest" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/ptrace" + conventions "go.opentelemetry.io/collector/semconv/v1.6.1" + "go.uber.org/zap" + "go.uber.org/zap/zaptest" + + integrationtestutils "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/splunkhecexporter/internal/integrationtestutils" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk" +) + +type SplunkContainerConfig struct { + conCtx context.Context + container testcontainers.Container +} + +func setup() SplunkContainerConfig { + // Perform setup operations here + fmt.Println("Setting up...") + cfg := startSplunk() + integrationtestutils.CreateAnIndexInSplunk(integrationtestutils.GetConfigVariable("EVENT_INDEX"), "event") + integrationtestutils.CreateAnIndexInSplunk(integrationtestutils.GetConfigVariable("METRIC_INDEX"), "metric") + integrationtestutils.CreateAnIndexInSplunk(integrationtestutils.GetConfigVariable("TRACE_INDEX"), "event") + fmt.Println("Index created") + return cfg +} + +func teardown(cfg SplunkContainerConfig) { + // Perform teardown operations here + fmt.Println("Tearing down...") + // Stop and remove the container + fmt.Println("Stopping container") + err := cfg.container.Terminate(cfg.conCtx) + if err != nil { + fmt.Printf("Error while terminiating container") + panic(err) + } + // Remove docker image after tests + splunkImage := integrationtestutils.GetConfigVariable("SPLUNK_IMAGE") + cmd := exec.Command("docker", "rmi", splunkImage) + + // Execute command + output, err := cmd.CombinedOutput() + if err != nil { + fmt.Printf("Error removing Docker image: %v\n", err) + } + fmt.Printf("Removed Docker image: %s\n", splunkImage) + fmt.Printf("Command output:\n%s\n", output) +} + +func TestMain(m *testing.M) { + splunkContCfg := setup() + + // Run the tests + code := m.Run() + + teardown(splunkContCfg) + // Exit with the test result code + os.Exit(code) +} + +func createInsecureClient() *http.Client { + // Create a custom transport with insecure settings + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + // Create the client with the custom transport + client := &http.Client{ + Transport: tr, + } + + return client +} + +func startSplunk() SplunkContainerConfig { + logger, err := zap.NewProduction() + if err != nil { + panic(err) + } + + conContext := context.Background() + + // Create a new container + splunkImage := integrationtestutils.GetConfigVariable("SPLUNK_IMAGE") + req := testcontainers.ContainerRequest{ + Image: splunkImage, + ExposedPorts: []string{"8000/tcp", "8088/tcp", "8089/tcp"}, + Env: map[string]string{ + "SPLUNK_START_ARGS": "--accept-license", + "SPLUNK_HEC_TOKEN": integrationtestutils.GetConfigVariable("HEC_TOKEN"), + "SPLUNK_PASSWORD": integrationtestutils.GetConfigVariable("PASSWORD"), + }, + WaitingFor: wait.ForLog("Ansible playbook complete, will begin streaming splunkd_stderr.log").WithStartupTimeout(2 * time.Minute), + } + + container, err := testcontainers.GenericContainer(conContext, testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + }) + + if err != nil { + logger.Info("Error while creating container") + panic(err) + } + + // Get the container host and port + uiPort, err := container.MappedPort(conContext, "8000") + if err != nil { + logger.Info("Error while getting port") + panic(err) + } + + hecPort, err := container.MappedPort(conContext, "8088") + if err != nil { + logger.Info("Error while getting port") + panic(err) + } + managementPort, err := container.MappedPort(conContext, "8089") + if err != nil { + logger.Info("Error while getting port") + panic(err) + } + host, err := container.Host(conContext) + if err != nil { + logger.Info("Error while getting host") + panic(err) + } + + // Use the container's host and port for your tests + logger.Info("Splunk running at:", zap.String("host", host), zap.Int("uiPort", uiPort.Int()), zap.Int("hecPort", hecPort.Int()), zap.Int("managementPort", managementPort.Int())) + integrationtestutils.SetConfigVariable("HOST", host) + integrationtestutils.SetConfigVariable("UI_PORT", strconv.Itoa(uiPort.Int())) + integrationtestutils.SetConfigVariable("HEC_PORT", strconv.Itoa(hecPort.Int())) + integrationtestutils.SetConfigVariable("MANAGEMENT_PORT", strconv.Itoa(managementPort.Int())) + cfg := SplunkContainerConfig{ + conCtx: conContext, + container: container, + } + return cfg +} + +func prepareLogs() plog.Logs { + logs := plog.NewLogs() + rl := logs.ResourceLogs().AppendEmpty() + sl := rl.ScopeLogs().AppendEmpty() + sl.Scope().SetName("test") + ts := pcommon.Timestamp(0) + logRecord := sl.LogRecords().AppendEmpty() + logRecord.Body().SetStr("test log") + logRecord.Attributes().PutStr(splunk.DefaultNameLabel, "test- label") + logRecord.Attributes().PutStr(conventions.AttributeHostName, "myhost") + logRecord.Attributes().PutStr("custom", "custom") + logRecord.SetTimestamp(ts) + return logs +} + +func prepareLogsNonDefaultParams(index string, source string, sourcetype string, event string) plog.Logs { + logs := plog.NewLogs() + rl := logs.ResourceLogs().AppendEmpty() + sl := rl.ScopeLogs().AppendEmpty() + sl.Scope().SetName("test") + ts := pcommon.Timestamp(0) + + logRecord := sl.LogRecords().AppendEmpty() + logRecord.Body().SetStr(event) + logRecord.Attributes().PutStr(splunk.DefaultNameLabel, "label") + logRecord.Attributes().PutStr(splunk.DefaultSourceLabel, source) + logRecord.Attributes().PutStr(splunk.DefaultSourceTypeLabel, sourcetype) + logRecord.Attributes().PutStr(splunk.DefaultIndexLabel, index) + logRecord.Attributes().PutStr(conventions.AttributeHostName, "myhost") + logRecord.Attributes().PutStr("custom", "custom") + logRecord.SetTimestamp(ts) + return logs +} + +func prepareMetricsData(metricName string) pmetric.Metrics { + metricData := pmetric.NewMetrics() + metric := metricData.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty() + g := metric.SetEmptyGauge() + g.DataPoints().AppendEmpty().SetDoubleValue(132.929) + metric.SetName(metricName) + return metricData +} + +func prepareTracesData(index string, source string, sourcetype string) ptrace.Traces { + ts := pcommon.Timestamp(0) + + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr("com.splunk.source", source) + rs.Resource().Attributes().PutStr("host.name", "myhost") + rs.Resource().Attributes().PutStr("com.splunk.sourcetype", sourcetype) + rs.Resource().Attributes().PutStr("com.splunk.index", index) + ils := rs.ScopeSpans().AppendEmpty() + initSpan("myspan", ts, ils.Spans().AppendEmpty()) + return traces +} + +func TestSplunkHecExporterEventsToSplunk(t *testing.T) { + logger := zaptest.NewLogger(t) + logger.Info("Test -> Splunk running at:", zap.String("host", integrationtestutils.GetConfigVariable("HOST")), + zap.String("uiPort", integrationtestutils.GetConfigVariable("UI_PORT")), + zap.String("hecPort", integrationtestutils.GetConfigVariable("HEC_PORT")), + zap.String("managementPort", integrationtestutils.GetConfigVariable("MANAGEMENT_PORT")), + ) + // Endpoint and Token do not have a default value so set them directly. + config := NewFactory().CreateDefaultConfig().(*Config) + config.Token = configopaque.String(integrationtestutils.GetConfigVariable("HEC_TOKEN")) + config.HTTPClientSettings.Endpoint = "https://" + integrationtestutils.GetConfigVariable("HOST") + ":" + integrationtestutils.GetConfigVariable("HEC_PORT") + "/services/collector" + config.Source = "otel" + config.SourceType = "st-otel" + config.Index = "main" + config.TLSSetting.InsecureSkipVerify = true + + url, err := config.getURL() + require.NoError(t, err, "Must not error while getting URL") + settings := exportertest.NewNopCreateSettings() + c := newLogsClient(settings, config) + logs := prepareLogs() + httpClient := createInsecureClient() + c.hecWorker = &defaultHecWorker{url, httpClient, buildHTTPHeaders(config, component.NewDefaultBuildInfo())} + + err = c.pushLogData(context.Background(), logs) + require.NoError(t, err, "Must not error while sending Logs data") + waitForEventToBeIndexed() + + query := "index=main *" + events := integrationtestutils.CheckEventsFromSplunk(query, "-3h@h") + logger.Info("Splunk received %d events in the last minute", zap.Int("no. of events", len(events))) + assert.True(t, len(events) == 1) + // check events fields + data, ok := events[0].(map[string]interface{}) + if !ok { + logger.Info("Invalid event format") + } + assert.True(t, "test log" == data["_raw"].(string)) + assert.True(t, "main" == data["index"].(string)) + assert.True(t, "otel" == data["source"].(string)) + assert.True(t, "st-otel" == data["sourcetype"].(string)) +} + +func TestSplunkHecExporterEventsToSplunkNonDefaultIndex(t *testing.T) { + logger := zaptest.NewLogger(t) + logger.Info("Test -> Splunk running at:", zap.String("host", integrationtestutils.GetConfigVariable("HOST")), + zap.String("uiPort", integrationtestutils.GetConfigVariable("UI_PORT")), + zap.String("hecPort", integrationtestutils.GetConfigVariable("HEC_PORT")), + zap.String("managementPort", integrationtestutils.GetConfigVariable("MANAGEMENT_PORT")), + ) + + event := "This is my new event! And some number 101" + index := integrationtestutils.GetConfigVariable("EVENT_INDEX") + source := "otel-source" + sourcetype := "sck-otel-st" + + // Endpoint and Token do not have a default value so set them directly. + config := NewFactory().CreateDefaultConfig().(*Config) + config.Token = configopaque.String(integrationtestutils.GetConfigVariable("HEC_TOKEN")) + config.HTTPClientSettings.Endpoint = "https://" + integrationtestutils.GetConfigVariable("HOST") + ":" + integrationtestutils.GetConfigVariable("HEC_PORT") + "/services/collector" + config.Source = "otel" + config.SourceType = "st-otel" + config.Index = "main" + config.TLSSetting.InsecureSkipVerify = true + + url, err := config.getURL() + require.NoError(t, err, "Must not error while getting URL") + settings := exportertest.NewNopCreateSettings() + c := newLogsClient(settings, config) + logs := prepareLogsNonDefaultParams(index, source, sourcetype, event) + httpClient := createInsecureClient() + c.hecWorker = &defaultHecWorker{url, httpClient, buildHTTPHeaders(config, component.NewDefaultBuildInfo())} + + err = c.pushLogData(context.Background(), logs) + require.NoError(t, err, "Must not error while sending Logs data") + waitForEventToBeIndexed() + + query := "index=" + index + " *" + events := integrationtestutils.CheckEventsFromSplunk(query, "-1m@m") + logger.Info("Splunk received %d events in the last minute", zap.Int("no. of events", len(events))) + assert.True(t, len(events) == 1) + // check events fields + data, ok := events[0].(map[string]interface{}) + if !ok { + logger.Info("Invalid event format") + } + assert.True(t, event == data["_raw"].(string)) + assert.True(t, index == data["index"].(string)) + assert.True(t, source == data["source"].(string)) + assert.True(t, sourcetype == data["sourcetype"].(string)) +} + +func TestSplunkHecExporterMetricsToSplunk(t *testing.T) { + logger := zaptest.NewLogger(t) + logger.Info("Test -> Splunk running at:", zap.String("host", integrationtestutils.GetConfigVariable("HOST")), + zap.String("uiPort", integrationtestutils.GetConfigVariable("UI_PORT")), + zap.String("hecPort", integrationtestutils.GetConfigVariable("HEC_PORT")), + zap.String("managementPort", integrationtestutils.GetConfigVariable("MANAGEMENT_PORT")), + ) + index := integrationtestutils.GetConfigVariable("METRIC_INDEX") + metricName := "test.metric" + // Endpoint and Token do not have a default value so set them directly. + config := NewFactory().CreateDefaultConfig().(*Config) + config.Token = configopaque.String(integrationtestutils.GetConfigVariable("HEC_TOKEN")) + config.HTTPClientSettings.Endpoint = "https://" + integrationtestutils.GetConfigVariable("HOST") + ":" + integrationtestutils.GetConfigVariable("HEC_PORT") + "/services/collector" + config.Source = "otel" + config.SourceType = "st-otel" + config.Index = index + config.TLSSetting.InsecureSkipVerify = true + + url, err := config.getURL() + require.NoError(t, err, "Must not error while getting URL") + settings := exportertest.NewNopCreateSettings() + c := newMetricsClient(settings, config) + metricData := prepareMetricsData(metricName) + + httpClient := createInsecureClient() + c.hecWorker = &defaultHecWorker{url, httpClient, buildHTTPHeaders(config, component.NewDefaultBuildInfo())} + + err = c.pushMetricsData(context.Background(), metricData) + require.NoError(t, err, "Must not error while sending Metrics data") + waitForEventToBeIndexed() + + events := integrationtestutils.CheckMetricsFromSplunk(index, metricName) + assert.True(t, len(events) == 1, "Events length is less than 1. No metrics found") +} + +func TestSplunkHecExporterTracesToSplunk(t *testing.T) { + logger := zaptest.NewLogger(t) + logger.Info("Test -> Splunk running at:", zap.String("host", integrationtestutils.GetConfigVariable("HOST")), + zap.String("uiPort", integrationtestutils.GetConfigVariable("UI_PORT")), + zap.String("hecPort", integrationtestutils.GetConfigVariable("HEC_PORT")), + zap.String("managementPort", integrationtestutils.GetConfigVariable("MANAGEMENT_PORT")), + ) + index := integrationtestutils.GetConfigVariable("TRACE_INDEX") + source := "trace-source" + sourcetype := "trace-sourcetype" + // Endpoint and Token do not have a default value so set them directly. + config := NewFactory().CreateDefaultConfig().(*Config) + config.Token = configopaque.String(integrationtestutils.GetConfigVariable("HEC_TOKEN")) + config.HTTPClientSettings.Endpoint = "https://" + integrationtestutils.GetConfigVariable("HOST") + ":" + integrationtestutils.GetConfigVariable("HEC_PORT") + "/services/collector" + config.Source = "otel" + config.SourceType = "st-otel" + config.Index = "main" + config.TLSSetting.InsecureSkipVerify = true + + url, err := config.getURL() + require.NoError(t, err, "Must not error while getting URL") + settings := exportertest.NewNopCreateSettings() + c := newTracesClient(settings, config) + tracesData := prepareTracesData(index, source, sourcetype) + + httpClient := createInsecureClient() + c.hecWorker = &defaultHecWorker{url, httpClient, buildHTTPHeaders(config, component.NewDefaultBuildInfo())} + + err = c.pushTraceData(context.Background(), tracesData) + require.NoError(t, err, "Must not error while sending Trace data") + + waitForEventToBeIndexed() + query := "index=" + index + " *" + events := integrationtestutils.CheckEventsFromSplunk(query, "-1m@m") + logger.Info("Splunk received %d events in the last minute", zap.Int("no. of events", len(events))) + assert.True(t, len(events) == 1) + // check fields + data, ok := events[0].(map[string]interface{}) + if !ok { + logger.Info("Invalid event format") + } + assert.True(t, index == data["index"].(string)) + assert.True(t, source == data["source"].(string)) + assert.True(t, sourcetype == data["sourcetype"].(string)) +} + +func waitForEventToBeIndexed() { + time.Sleep(3 * time.Second) +} diff --git a/exporter/splunkhecexporter/internal/integrationtestutils/config_helper.go b/exporter/splunkhecexporter/internal/integrationtestutils/config_helper.go new file mode 100644 index 000000000000..3576f16da978 --- /dev/null +++ b/exporter/splunkhecexporter/internal/integrationtestutils/config_helper.go @@ -0,0 +1,113 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package integrationtestutils // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/splunkhecexporter/internal/integrationtestutils" + +import ( + "fmt" + "os" + + "gopkg.in/yaml.v3" +) + +var configFilePth = "./testdata/integration_tests_config.yaml" + +type IntegrationTestsConfig struct { + Host string `yaml:"HOST"` + User string `yaml:"USER"` + Password string `yaml:"PASSWORD"` + UIPort string `yaml:"UI_PORT"` + HecPort string `yaml:"HEC_PORT"` + ManagementPort string `yaml:"MANAGEMENT_PORT"` + EventIndex string `yaml:"EVENT_INDEX"` + MetricIndex string `yaml:"METRIC_INDEX"` + TraceIndex string `yaml:"TRACE_INDEX"` + HecToken string `yaml:"HEC_TOKEN"` + SplunkImage string `yaml:"SPLUNK_IMAGE"` +} + +func GetConfigVariable(key string) string { + // Read YAML file + fileData, err := os.ReadFile(configFilePth) + if err != nil { + fmt.Println("Error reading file:", err) + } + + var config IntegrationTestsConfig + err = yaml.Unmarshal(fileData, &config) + if err != nil { + fmt.Println("Error decoding YAML:", err) + } + + switch key { + case "HOST": + return config.Host + case "USER": + return config.User + case "PASSWORD": + return config.Password + case "UI_PORT": + return config.UIPort + case "HEC_PORT": + return config.HecPort + case "MANAGEMENT_PORT": + return config.ManagementPort + case "EVENT_INDEX": + return config.EventIndex + case "METRIC_INDEX": + return config.MetricIndex + case "TRACE_INDEX": + return config.TraceIndex + case "HEC_TOKEN": + return config.HecToken + case "SPLUNK_IMAGE": + return config.SplunkImage + default: + fmt.Println("Invalid field") + return "None" + } +} + +func SetConfigVariable(key string, value string) { + // Read YAML file + fileData, err := os.ReadFile(configFilePth) + if err != nil { + fmt.Println("Error reading file:", err) + } + + var config IntegrationTestsConfig + err = yaml.Unmarshal(fileData, &config) + if err != nil { + fmt.Printf("Error unmarshaling YAML: %v", err) + } + + switch key { + case "HOST": + config.Host = value + case "UI_PORT": + config.UIPort = value + case "HEC_PORT": + config.HecPort = value + case "MANAGEMENT_PORT": + config.ManagementPort = value + case "EVENT_INDEX": + default: + fmt.Println("Invalid field") + } + // Marshal updated Config into YAML + newData, err := yaml.Marshal(&config) + if err != nil { + fmt.Printf("Error marshaling YAML: %v", err) + return + } + + // Write yaml file + err = os.WriteFile(configFilePth, newData, os.ModePerm) + if err != nil { + fmt.Printf("Error writing file: %v", err) + return + } + + fmt.Println("Host value updated successfully!") + +} diff --git a/exporter/splunkhecexporter/internal/integrationtestutils/splunk.go b/exporter/splunkhecexporter/internal/integrationtestutils/splunk.go new file mode 100644 index 000000000000..09a603db83c7 --- /dev/null +++ b/exporter/splunkhecexporter/internal/integrationtestutils/splunk.go @@ -0,0 +1,227 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package integrationtestutils // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/splunkhecexporter/internal/integrationtestutils" + +import ( + "crypto/tls" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "net/url" + "os" + "strconv" + "strings" + "time" +) + +func CheckEventsFromSplunk(searchQuery string, startTime string, endTimeOptional ...string) []interface{} { + logger := log.New(os.Stdout, "", log.LstdFlags) + logger.Println("-->> Splunk Search: checking events in Splunk --") + user := GetConfigVariable("USER") + password := GetConfigVariable("PASSWORD") + baseURL := "https://" + GetConfigVariable("HOST") + ":" + GetConfigVariable("MANAGEMENT_PORT") + endTime := "now" + if len(endTimeOptional) > 0 { + endTime = endTimeOptional[0] + } + // post search + jobID := postSearchRequest(user, password, baseURL, searchQuery, startTime, endTime) + // wait for search status done == true + for i := 0; i < 20; i++ { // limit loop - not allowing infinite looping + logger.Println("Checking Search Status ...") + isDone := checkSearchJobStatusCode(user, password, baseURL, jobID) + if isDone == true { + break + } + time.Sleep(1 * time.Second) + } + // get events + results := getSplunkSearchResults(user, password, baseURL, jobID) + return results +} + +func getSplunkSearchResults(user string, password string, baseURL string, jobID string) []interface{} { + logger := log.New(os.Stdout, "", log.LstdFlags) + eventURL := fmt.Sprintf("%s/services/search/jobs/%s/events?output_mode=json", baseURL, jobID) + logger.Println("URL: " + eventURL) + reqEvents, err := http.NewRequest("GET", eventURL, nil) + if err != nil { + panic(err) + } + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + reqEvents.SetBasicAuth(user, password) + respEvents, err := client.Do(reqEvents) + if err != nil { + panic(err) + } + defer respEvents.Body.Close() + logger.Println("Send Request: Get query status code: " + strconv.Itoa(respEvents.StatusCode)) + + bodyEvents, err := io.ReadAll(respEvents.Body) + if err != nil { + panic(err) + } + + var jsonResponseEvents map[string]interface{} + err = json.Unmarshal(bodyEvents, &jsonResponseEvents) + if err != nil { + panic(err) + } + + // logger.Println("json Response Events --->") # debug + // logger.Println(jsonResponseEvents) # debug + results := jsonResponseEvents["results"].([]interface{}) + // logger.Println(results) + return results +} + +func checkSearchJobStatusCode(user string, password string, baseURL string, jobID string) interface{} { + logger := log.New(os.Stdout, "", log.LstdFlags) + checkEventURL := baseURL + "/services/search/jobs/" + jobID + "?output_mode=json" + logger.Println("URL: " + checkEventURL) + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + checkReqEvents, err := http.NewRequest("GET", checkEventURL, nil) + if err != nil { + panic(err) + } + checkReqEvents.SetBasicAuth(user, password) + checkResp, err := client.Do(checkReqEvents) + if err != nil { + panic(err) + } + defer checkResp.Body.Close() + logger.Println("Send Request: Check query status code: " + strconv.Itoa(checkResp.StatusCode)) + checkBody, err := io.ReadAll(checkResp.Body) + if err != nil { + panic(err) + } + var checkJSONResponse map[string]interface{} + err = json.Unmarshal(checkBody, &checkJSONResponse) + if err != nil { + panic(err) + } + // logger.Println(checkJSONResponse) // debug + // Print isDone field from response + isDone := checkJSONResponse["entry"].([]interface{})[0].(map[string]interface{})["content"].(map[string]interface{})["isDone"] + logger.Printf("Is Splunk Search compleated [isDone flag]: %v\n", isDone) + return isDone +} +func postSearchRequest(user string, password string, baseURL string, searchQuery string, startTime string, endTime string) string { + logger := log.New(os.Stdout, "", log.LstdFlags) + searchURL := fmt.Sprintf("%s/services/search/jobs?output_mode=json", baseURL) + query := "search " + searchQuery + logger.Println("Search query: " + query) + data := url.Values{} + data.Set("search", query) + data.Set("earliest_time", startTime) + data.Set("latest_time", endTime) + + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + req, err := http.NewRequest("POST", searchURL, strings.NewReader(data.Encode())) + if err != nil { + logger.Printf("Error while preparing POST request") + panic(err) + } + req.SetBasicAuth(user, password) + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + resp, err := client.Do(req) + if err != nil { + logger.Printf("Error while executing Http POST request") + panic(err) + } + defer resp.Body.Close() + logger.Println("Send Request: Post query status code: " + strconv.Itoa(resp.StatusCode)) + + body, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + var jsonResponse map[string]interface{} + err = json.Unmarshal(body, &jsonResponse) + if err != nil { + panic(err) + } + logger.Println(jsonResponse) // debug + return jsonResponse["sid"].(string) +} + +func CheckMetricsFromSplunk(index string, metricName string) []interface{} { + logger := log.New(os.Stdout, "", log.LstdFlags) + logger.Println("-->> Splunk Search: checking metrics in Splunk --") + baseURL := "https://" + GetConfigVariable("HOST") + ":" + GetConfigVariable("MANAGEMENT_PORT") + startTime := "-1d@d" + endTime := "now" + user := GetConfigVariable("USER") + password := GetConfigVariable("PASSWORD") + + apiURL := fmt.Sprintf("%s/services/catalog/metricstore/dimensions/host/values?filter=index%%3d%s&metric_name=%s&earliest=%s&latest=%s&output_mode=json", baseURL, index, metricName, startTime, endTime) + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr, Timeout: 10 * time.Second} + req, err := http.NewRequest("GET", apiURL, nil) + if err != nil { + panic(err) + } + req.SetBasicAuth(user, password) + + resp, err := client.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + var data map[string]interface{} + if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { + panic(err) + } + + events := data["entry"].([]interface{}) + // logger.Println(events) // debug + + return events +} + +func CreateAnIndexInSplunk(index string, indexType string) { + logger := log.New(os.Stdout, "", log.LstdFlags) + user := GetConfigVariable("USER") + password := GetConfigVariable("PASSWORD") + indexURL := "https://" + GetConfigVariable("HOST") + ":" + GetConfigVariable("MANAGEMENT_PORT") + "/services/data/indexes" + logger.Println("URL: " + indexURL) + data := url.Values{} + data.Set("name", index) + data.Set("datatype", indexType) + + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + req, err := http.NewRequest("POST", indexURL, strings.NewReader(data.Encode())) + if err != nil { + logger.Printf("Error while preparing POST request") + panic(err) + } + req.SetBasicAuth(user, password) + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + resp, err := client.Do(req) + if err != nil { + logger.Printf("Error while executing Http POST request") + panic(err) + } + defer resp.Body.Close() + logger.Println("Create index request status code: " + strconv.Itoa(resp.StatusCode)) +} diff --git a/exporter/splunkhecexporter/testdata/integration_tests_config.yaml b/exporter/splunkhecexporter/testdata/integration_tests_config.yaml new file mode 100644 index 000000000000..462b8bb3702d --- /dev/null +++ b/exporter/splunkhecexporter/testdata/integration_tests_config.yaml @@ -0,0 +1,20 @@ +# SPLUNK DATA +SPLUNK_IMAGE : "splunk/splunk:9.1" +HOST : "non" + +#credentials: +USER : "admin" +PASSWORD : "helloworld" + +# ports +UI_PORT: "8000" +HEC_PORT: "8088" +MANAGEMENT_PORT: "8089" + +# indexes +EVENT_INDEX : "sck-otel" +METRIC_INDEX: "sck-metrics" +TRACE_INDEX: "sck-traces" + +# hec tokens +HEC_TOKEN : "00000000-0000-0000-0000-000000000000" \ No newline at end of file diff --git a/extension/observer/dockerobserver/integration_test.go b/extension/observer/dockerobserver/integration_test.go index ae3f37b84f7b..d9cf2e720935 100644 --- a/extension/observer/dockerobserver/integration_test.go +++ b/extension/observer/dockerobserver/integration_test.go @@ -66,7 +66,6 @@ func TestObserverEmitsEndpointsIntegration(t *testing.T) { defer stopObserver(t, obvs) require.Eventually(t, func() bool { return mn.AddCount() == 1 }, 3*time.Second, 10*time.Millisecond) endpoints := mn.EndpointsMap() - require.Equal(t, len(endpoints), 2) found := false for _, e := range endpoints { if e.Details.Env()["image"] == "docker.io/library/nginx" { @@ -108,7 +107,6 @@ func TestObserverUpdatesEndpointsIntegration(t *testing.T) { defer stopObserver(t, obvs) require.Eventually(t, func() bool { return mn.AddCount() == 1 }, 3*time.Second, 10*time.Millisecond) endpoints := mn.EndpointsMap() - require.Equal(t, 2, len(endpoints)) found := false for _, e := range endpoints { if image == e.Details.Env()["image"] { @@ -165,7 +163,6 @@ func TestObserverRemovesEndpointsIntegration(t *testing.T) { defer stopObserver(t, obvs) require.Eventually(t, func() bool { return mn.AddCount() == 1 }, 3*time.Second, 10*time.Millisecond) endpoints := mn.EndpointsMap() - require.Equal(t, 2, len(endpoints)) found := false for _, e := range endpoints { if image == e.Details.Env()["image"] { @@ -181,7 +178,6 @@ func TestObserverRemovesEndpointsIntegration(t *testing.T) { require.Nil(t, err) require.Eventually(t, func() bool { return mn.RemoveCount() == 1 }, 3*time.Second, 10*time.Millisecond) - require.Len(t, mn.EndpointsMap(), 1) } func TestObserverExcludesImagesIntegration(t *testing.T) { @@ -212,7 +208,6 @@ func TestObserverExcludesImagesIntegration(t *testing.T) { time.Sleep(2 * time.Second) // wait for endpoints to sync require.Equal(t, 1, mn.AddCount()) require.Equal(t, 0, mn.ChangeCount()) - require.Len(t, mn.EndpointsMap(), 1) } func startObserver(t *testing.T, listener observer.Notify) *dockerObserver { diff --git a/receiver/splunkhecreceiver/go.sum b/receiver/splunkhecreceiver/go.sum index f27a7981fe1b..2ed76e01dc6e 100644 --- a/receiver/splunkhecreceiver/go.sum +++ b/receiver/splunkhecreceiver/go.sum @@ -1,6 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= @@ -9,9 +13,15 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -27,6 +37,7 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -57,6 +68,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -73,6 +85,8 @@ github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g= github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -80,13 +94,22 @@ github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmL github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= @@ -96,6 +119,9 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -105,8 +131,12 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/testcontainers/testcontainers-go v0.25.0 h1:erH6cQjsaJrH+rJDU9qIf89KFdhK0Bft0aEZHlYC3Vs= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/collector v0.87.1-0.20231017160804-ec0725874313 h1:20fAuaqh24+cyQbkCErALoRjYdCfnV4wTWgDcZoOao8= @@ -165,11 +195,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 h1:FqrVOBQxQ8r/UwwXibI0KMolVhvFiGobSfdE33deHJM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -206,6 +238,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 5d62df755fcc76c2e0dfad29b6d7fdf0f01dd1af Mon Sep 17 00:00:00 2001 From: Pawel Szkamruk Date: Wed, 25 Oct 2023 10:39:53 +0200 Subject: [PATCH 8/8] make gotidy --- exporter/splunkhecexporter/go.mod | 35 ++++++++- exporter/splunkhecexporter/go.sum | 122 ++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/exporter/splunkhecexporter/go.mod b/exporter/splunkhecexporter/go.mod index 2e274375c28c..a735077c31b6 100644 --- a/exporter/splunkhecexporter/go.mod +++ b/exporter/splunkhecexporter/go.mod @@ -10,6 +10,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.88.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.88.0 github.com/stretchr/testify v1.8.4 + github.com/testcontainers/testcontainers-go v0.25.0 go.opencensus.io v0.24.0 go.opentelemetry.io/collector/component v0.88.0 go.opentelemetry.io/collector/config/confighttp v0.88.0 @@ -22,30 +23,60 @@ require ( go.opentelemetry.io/collector/semconv v0.88.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/containerd/containerd v1.7.6 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.6+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/klauspost/compress v1.17.2 // indirect github.com/knadh/koanf/maps v0.1.1 // indirect github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.0.1 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/patternmatcher v0.5.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.88.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/runc v1.1.5 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/rs/cors v1.10.1 // indirect + github.com/shirou/gopsutil/v3 v3.23.9 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect go.opentelemetry.io/collector v0.88.0 // indirect go.opentelemetry.io/collector/config/configauth v0.88.0 // indirect go.opentelemetry.io/collector/config/configcompression v0.88.0 // indirect @@ -58,13 +89,15 @@ require ( go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect + golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal diff --git a/exporter/splunkhecexporter/go.sum b/exporter/splunkhecexporter/go.sum index 98dde9771be9..7b86087cb7bb 100644 --- a/exporter/splunkhecexporter/go.sum +++ b/exporter/splunkhecexporter/go.sum @@ -1,23 +1,53 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= +github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= +github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= +github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= @@ -27,6 +57,10 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -53,10 +87,15 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -69,8 +108,15 @@ github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPgh github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g= github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -78,13 +124,35 @@ github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmL github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= @@ -94,17 +162,43 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= +github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/testcontainers/testcontainers-go v0.25.0 h1:erH6cQjsaJrH+rJDU9qIf89KFdhK0Bft0aEZHlYC3Vs= +github.com/testcontainers/testcontainers-go v0.25.0/go.mod h1:4sC9SiJyzD1XFi59q8umTQYWxnkweEc5OjVtTUlJzqQ= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/collector v0.88.0 h1:I0lerJK1h88vk7enriSgLV+h7dM099G9FgwkfmIZaf0= @@ -161,11 +255,15 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 h1:FqrVOBQxQ8r/UwwXibI0KMolVhvFiGobSfdE33deHJM= +golang.org/x/exp v0.0.0-20230711023510-fffb14384f22/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -175,6 +273,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -183,16 +282,34 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -201,6 +318,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -230,13 +349,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=