krkn-lib 0.0.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- krkn_lib/elastic/__init__.py +1 -0
- krkn_lib/elastic/krkn_elastic.py +246 -0
- krkn_lib/k8s/__init__.py +1 -0
- krkn_lib/k8s/krkn_kubernetes.py +3496 -0
- krkn_lib/k8s/pods_monitor_pool.py +202 -0
- krkn_lib/k8s/templates/hog_pod.j2 +55 -0
- krkn_lib/k8s/templates/node_exec_pod.j2 +30 -0
- krkn_lib/k8s/templates/service_hijacking_config_map.j2 +8 -0
- krkn_lib/k8s/templates/service_hijacking_pod.j2 +31 -0
- krkn_lib/k8s/templates/syn_flood_pod.j2 +41 -0
- krkn_lib/models/__init__.py +0 -0
- krkn_lib/models/elastic/__init__.py +1 -0
- krkn_lib/models/elastic/models.py +234 -0
- krkn_lib/models/k8s/__init__.py +1 -0
- krkn_lib/models/k8s/models.py +406 -0
- krkn_lib/models/krkn/__init__.py +1 -0
- krkn_lib/models/krkn/models.py +236 -0
- krkn_lib/models/telemetry/__init__.py +1 -0
- krkn_lib/models/telemetry/models.py +562 -0
- krkn_lib/ocp/__init__.py +1 -0
- krkn_lib/ocp/krkn_openshift.py +482 -0
- krkn_lib/prometheus/__init__.py +0 -0
- krkn_lib/prometheus/krkn_prometheus.py +257 -0
- krkn_lib/telemetry/__init__.py +0 -0
- krkn_lib/telemetry/k8s/__init__.py +1 -0
- krkn_lib/telemetry/k8s/krkn_telemetry_kubernetes.py +645 -0
- krkn_lib/telemetry/ocp/__init__.py +1 -0
- krkn_lib/telemetry/ocp/krkn_telemetry_openshift.py +264 -0
- krkn_lib/tests/__init__.py +1 -0
- krkn_lib/tests/base_test.py +582 -0
- krkn_lib/tests/test_krkn_elastic.py +170 -0
- krkn_lib/tests/test_krkn_elastic_models.py +235 -0
- krkn_lib/tests/test_krkn_kubernetes_check.py +230 -0
- krkn_lib/tests/test_krkn_kubernetes_create.py +70 -0
- krkn_lib/tests/test_krkn_kubernetes_delete.py +124 -0
- krkn_lib/tests/test_krkn_kubernetes_exec.py +198 -0
- krkn_lib/tests/test_krkn_kubernetes_get.py +351 -0
- krkn_lib/tests/test_krkn_kubernetes_list.py +145 -0
- krkn_lib/tests/test_krkn_kubernetes_misc.py +349 -0
- krkn_lib/tests/test_krkn_kubernetes_models.py +169 -0
- krkn_lib/tests/test_krkn_kubernetes_monitor.py +367 -0
- krkn_lib/tests/test_krkn_kubernetes_pods_monitor_pool.py +128 -0
- krkn_lib/tests/test_krkn_openshift.py +123 -0
- krkn_lib/tests/test_krkn_prometheus.py +234 -0
- krkn_lib/tests/test_krkn_telemetry_kubernetes.py +326 -0
- krkn_lib/tests/test_krkn_telemetry_models.py +438 -0
- krkn_lib/tests/test_krkn_telemetry_openshift.py +56 -0
- krkn_lib/tests/test_utils.py +412 -0
- krkn_lib/tests/test_version.py +8 -0
- krkn_lib/utils/__init__.py +2 -0
- krkn_lib/utils/functions.py +459 -0
- krkn_lib/utils/safe_logger.py +121 -0
- krkn_lib/version/__init__.py +1 -0
- krkn_lib/version/version.py +3 -0
- krkn_lib-0.0.0b0.dist-info/LICENSE +177 -0
- krkn_lib-0.0.0b0.dist-info/METADATA +68 -0
- krkn_lib-0.0.0b0.dist-info/RECORD +58 -0
- krkn_lib-0.0.0b0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .krkn_elastic import * # NOQA
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import math
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
import urllib3
|
|
8
|
+
from elasticsearch import Elasticsearch, NotFoundError
|
|
9
|
+
from elasticsearch_dsl import Search
|
|
10
|
+
|
|
11
|
+
from krkn_lib.models.elastic.models import (
|
|
12
|
+
ElasticAlert,
|
|
13
|
+
ElasticChaosRunTelemetry,
|
|
14
|
+
ElasticMetric,
|
|
15
|
+
)
|
|
16
|
+
from krkn_lib.models.telemetry import ChaosRunTelemetry
|
|
17
|
+
from krkn_lib.utils.safe_logger import SafeLogger
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class KrknElastic:
|
|
21
|
+
es = None
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
safe_logger: SafeLogger,
|
|
26
|
+
elastic_url: str,
|
|
27
|
+
elastic_port: int = 443,
|
|
28
|
+
verify_certs: bool = False,
|
|
29
|
+
username: str = None,
|
|
30
|
+
password: str = None,
|
|
31
|
+
):
|
|
32
|
+
es_logger = logging.getLogger("elasticsearch")
|
|
33
|
+
es_logger.setLevel(logging.WARNING)
|
|
34
|
+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
35
|
+
urllib3.disable_warnings(DeprecationWarning)
|
|
36
|
+
es_transport_logger = logging.getLogger("elastic_transport.transport")
|
|
37
|
+
es_transport_logger.setLevel(logging.CRITICAL)
|
|
38
|
+
self.safe_logger = safe_logger
|
|
39
|
+
try:
|
|
40
|
+
if not elastic_url:
|
|
41
|
+
raise Exception("elastic search url is not valid")
|
|
42
|
+
if not elastic_port:
|
|
43
|
+
raise Exception("elastic port is not valid")
|
|
44
|
+
# create Elasticsearch object
|
|
45
|
+
|
|
46
|
+
credentials = (
|
|
47
|
+
(username, password) if username and password else None
|
|
48
|
+
)
|
|
49
|
+
self.es = Elasticsearch(
|
|
50
|
+
f"{elastic_url}:{elastic_port}",
|
|
51
|
+
http_auth=credentials,
|
|
52
|
+
verify_certs=verify_certs,
|
|
53
|
+
ssl_show_warn=False,
|
|
54
|
+
)
|
|
55
|
+
except Exception as e:
|
|
56
|
+
self.safe_logger.error("Failed to initalize elasticsearch: %s" % e)
|
|
57
|
+
raise e
|
|
58
|
+
|
|
59
|
+
def upload_data_to_elasticsearch(self, item: dict, index: str = "") -> int:
|
|
60
|
+
"""uploads captured data in item dictionary to Elasticsearch
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
:param item: the data to post to elastic search
|
|
64
|
+
:param index: the elastic search index pattern to post to
|
|
65
|
+
|
|
66
|
+
:return: the time taken to post the result,
|
|
67
|
+
will be 0 if index and es are blank
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
if self.es and index != "":
|
|
71
|
+
# Attach to elastic search and attempt index creation
|
|
72
|
+
start = time.time()
|
|
73
|
+
self.safe_logger.info(
|
|
74
|
+
f"Uploading item {item} to index {index} in Elasticsearch"
|
|
75
|
+
)
|
|
76
|
+
try:
|
|
77
|
+
response = self.es.index(index=index, body=item)
|
|
78
|
+
self.safe_logger.info(f"Response back was {response}")
|
|
79
|
+
if response["result"] != "created":
|
|
80
|
+
self.safe_logger.error(
|
|
81
|
+
f"Error trying to create new item in {index}"
|
|
82
|
+
)
|
|
83
|
+
return -1
|
|
84
|
+
except Exception as e:
|
|
85
|
+
self.safe_logger.error(f"Error trying to create new item: {e}")
|
|
86
|
+
return -1
|
|
87
|
+
end = time.time()
|
|
88
|
+
elapsed_time = end - start
|
|
89
|
+
|
|
90
|
+
# return elapsed time for upload if no issues
|
|
91
|
+
return math.ceil(elapsed_time)
|
|
92
|
+
return 0
|
|
93
|
+
|
|
94
|
+
def upload_metrics_to_elasticsearch(
|
|
95
|
+
self,
|
|
96
|
+
run_uuid: str,
|
|
97
|
+
raw_data: list[dict[str, str | int | float]],
|
|
98
|
+
index: str,
|
|
99
|
+
) -> int:
|
|
100
|
+
"""
|
|
101
|
+
Saves raw data returned from the Krkn prometheus
|
|
102
|
+
client to elastic search as a ElasticMetric object
|
|
103
|
+
raw data will be a mixed types dictionary in the format
|
|
104
|
+
{"name":"str", "values":[(10, '3.14'), (11,'3.15').....]
|
|
105
|
+
|
|
106
|
+
:param run_uuid: the krkn run id
|
|
107
|
+
:param raw_data: the mixed type dictionary (will be validated
|
|
108
|
+
checking the attributes types )
|
|
109
|
+
:param index: the elasticsearch index where
|
|
110
|
+
the object will be stored
|
|
111
|
+
:return: the time needed to save if succeeded -1 if failed
|
|
112
|
+
"""
|
|
113
|
+
if not index:
|
|
114
|
+
raise Exception("index cannot be None or empty")
|
|
115
|
+
if not run_uuid:
|
|
116
|
+
raise Exception("run uuid cannot be None or empty")
|
|
117
|
+
time_start = time.time()
|
|
118
|
+
try:
|
|
119
|
+
for metric in raw_data:
|
|
120
|
+
result = self.push_metric(
|
|
121
|
+
ElasticMetric(run_uuid=run_uuid, **metric),
|
|
122
|
+
index,
|
|
123
|
+
)
|
|
124
|
+
if result == -1:
|
|
125
|
+
self.safe_logger.error(
|
|
126
|
+
f"failed to save metric "
|
|
127
|
+
f"to elasticsearch : {metric}"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
return int(time.time() - time_start)
|
|
131
|
+
except Exception as e:
|
|
132
|
+
self.safe_logger.error(f"Upload metric exception: {e}")
|
|
133
|
+
return -1
|
|
134
|
+
|
|
135
|
+
def push_alert(self, alert: ElasticAlert, index: str) -> int:
|
|
136
|
+
"""
|
|
137
|
+
Pushes an ElasticAlert object to elastic
|
|
138
|
+
|
|
139
|
+
:param alert: the populated ElasticAlert object
|
|
140
|
+
:param index: the index where the ElasticAlert Object
|
|
141
|
+
is pushed
|
|
142
|
+
:return: the time needed to save if succeeded -1 if failed
|
|
143
|
+
"""
|
|
144
|
+
if not index:
|
|
145
|
+
raise Exception("index cannot be None or empty")
|
|
146
|
+
try:
|
|
147
|
+
time_start = time.time()
|
|
148
|
+
alert.save(using=self.es, index=index)
|
|
149
|
+
return int(time.time() - time_start)
|
|
150
|
+
except Exception as e:
|
|
151
|
+
self.safe_logger.error(f"Push alert exception: {e}")
|
|
152
|
+
return -1
|
|
153
|
+
|
|
154
|
+
def push_metric(self, metric: ElasticMetric, index: str) -> int:
|
|
155
|
+
"""
|
|
156
|
+
Pushes an ElasticMetric object to elastic
|
|
157
|
+
|
|
158
|
+
:param metric: the populated ElasticMetric object
|
|
159
|
+
:param index: the index where the ElasticMetric Object
|
|
160
|
+
is pushed
|
|
161
|
+
:return: the time needed to save if succeeded -1 if failed
|
|
162
|
+
"""
|
|
163
|
+
if not index:
|
|
164
|
+
raise Exception("index cannot be None or empty")
|
|
165
|
+
try:
|
|
166
|
+
time_start = time.time()
|
|
167
|
+
metric.save(using=self.es, index=index)
|
|
168
|
+
return int(time.time() - time_start)
|
|
169
|
+
except Exception as e:
|
|
170
|
+
print("error" + str(e))
|
|
171
|
+
self.safe_logger.error(f"Exception pushing metric: {e}")
|
|
172
|
+
return -1
|
|
173
|
+
|
|
174
|
+
def push_telemetry(self, telemetry: ChaosRunTelemetry, index: str):
|
|
175
|
+
if not index:
|
|
176
|
+
raise Exception("index cannot be None or empty")
|
|
177
|
+
try:
|
|
178
|
+
elastic_chaos = ElasticChaosRunTelemetry(telemetry)
|
|
179
|
+
time_start = time.time()
|
|
180
|
+
elastic_chaos.save(using=self.es, index=index)
|
|
181
|
+
return int(time.time() - time_start)
|
|
182
|
+
except Exception as e:
|
|
183
|
+
self.safe_logger.info(f"Elastic push telemetry error: {e}")
|
|
184
|
+
return -1
|
|
185
|
+
|
|
186
|
+
def search_telemetry(self, run_uuid: str, index: str):
|
|
187
|
+
"""
|
|
188
|
+
Searches ElasticChaosRunTelemetry by run_uuid
|
|
189
|
+
:param run_uuid: the Krkn run id to search
|
|
190
|
+
:param index: the index where the ElasticChaosRunTelemetry
|
|
191
|
+
should have been saved
|
|
192
|
+
:return: the list of objects retrieved (Empty if nothing
|
|
193
|
+
has been found)
|
|
194
|
+
"""
|
|
195
|
+
try:
|
|
196
|
+
search = Search(using=self.es, index=index).filter(
|
|
197
|
+
"match", run_uuid=run_uuid
|
|
198
|
+
)
|
|
199
|
+
result = search.execute()
|
|
200
|
+
documents = [
|
|
201
|
+
ElasticChaosRunTelemetry(**hit.to_dict()) for hit in result
|
|
202
|
+
]
|
|
203
|
+
except NotFoundError:
|
|
204
|
+
self.safe_logger.error("Search telemetry not found")
|
|
205
|
+
return []
|
|
206
|
+
return documents
|
|
207
|
+
|
|
208
|
+
def search_alert(self, run_uuid: str, index: str) -> list[ElasticAlert]:
|
|
209
|
+
"""
|
|
210
|
+
Searches ElasticAlerts by run_uuid
|
|
211
|
+
:param run_uuid: the Krkn run id to search
|
|
212
|
+
:param index: the index where the ElasticAlert
|
|
213
|
+
should have been saved
|
|
214
|
+
:return: the list of objects retrieved (Empty if nothing
|
|
215
|
+
has been found)
|
|
216
|
+
"""
|
|
217
|
+
try:
|
|
218
|
+
search = Search(using=self.es, index=index).filter(
|
|
219
|
+
"match", run_uuid=run_uuid
|
|
220
|
+
)
|
|
221
|
+
result = search.execute()
|
|
222
|
+
documents = [ElasticAlert(**hit.to_dict()) for hit in result]
|
|
223
|
+
except NotFoundError:
|
|
224
|
+
self.safe_logger.error("Search alert not found")
|
|
225
|
+
return []
|
|
226
|
+
return documents
|
|
227
|
+
|
|
228
|
+
def search_metric(self, run_uuid: str, index: str) -> list[ElasticMetric]:
|
|
229
|
+
"""
|
|
230
|
+
Searches ElasticMetric by run_uuid
|
|
231
|
+
:param run_uuid: the Krkn run id to search
|
|
232
|
+
:param index: the index where the ElasticAlert
|
|
233
|
+
should have been saved
|
|
234
|
+
:return: the list of objects retrieved (Empty if nothing
|
|
235
|
+
has been found)
|
|
236
|
+
"""
|
|
237
|
+
try:
|
|
238
|
+
search = Search(using=self.es, index=index).filter(
|
|
239
|
+
"match", run_uuid=run_uuid
|
|
240
|
+
)
|
|
241
|
+
result = search.execute()
|
|
242
|
+
documents = [ElasticMetric(**hit.to_dict()) for hit in result]
|
|
243
|
+
except NotFoundError:
|
|
244
|
+
self.safe_logger.error("Search metric not found")
|
|
245
|
+
return []
|
|
246
|
+
return documents
|
krkn_lib/k8s/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .krkn_kubernetes import * # NOQA
|