Skip to content

Commit d2f9be3

Browse files
committed
Add support for prometheus metrics
1 parent 4df21b4 commit d2f9be3

File tree

1 file changed

+38
-23
lines changed

1 file changed

+38
-23
lines changed

scripts/generate-kubernetes-cluster-representation-from-kubernetes-metrics-server-data.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
import argparse
33
import re
44
import collections
5+
from sqlalchemy import true
56
from termcolor import colored
67

78
"""
8-
Script to generate a representations from information leaked from an instance
9-
of Kubernetes Metrics Server via its endpoints "/metrics".
9+
Script to generate a representations from information leaked from an instance of Kubernetes Metrics Server via its endpoints "/metrics".
1010
11-
Also support output from an instance of Prometheus.
11+
Support also the output from an instance of an exporter for Prometheus that is using the Prometheus data format.
1212
1313
Command to get the data:
1414
@@ -29,25 +29,36 @@
2929
Dependencies:
3030
None
3131
32-
References:
32+
Resources:
3333
https://github.com/projectdiscovery/nuclei-templates/blob/main/http/technologies/kubernetes/kubelet/kubelet-metrics.yaml
3434
https://github.com/projectdiscovery/nuclei-templates/blob/main/http/exposures/configs/prometheus-metrics.yaml
3535
"""
36-
K8S_RESOURCE_TYPES = ["pod", "deployment", "service", "configmap", "node", "secret"]
37-
K8S_OTHERS_TYPES = ["controller", "host", "webhook"]
36+
K8S_RESOURCE_TYPES = ["pod", "deployment", "service", "configmap", "node", "secret", "replicaset", "daemonset", "networkpolicy", "statefulset"]
37+
K8S_OTHERS_TYPES = ["controller", "host", "webhook", "lease", "pod_cidr"]
38+
K8S_RESOURCE_TYPES.sort()
39+
K8S_OTHERS_TYPES.sort()
3840
NAMESPACE_REGEX = r'namespace="(.*?)"'
3941
RESOURCE_KEY = "resources"
4042
OTHER_KEY = "others"
4143
MISC_KEY = "misc"
4244

4345

46+
def is_name_not_none(name):
47+
return (name.lower().strip(" \t") != "<none>")
48+
49+
4450
def load_records(kms_data_file):
4551
# KEY is the namespace
4652
# VALUE is a DICT for which KEY is the K8S resource type and VALUE is a list of the related K8S resource/component names
4753
records = {}
4854
with open(kms_data_file, mode="r", encoding="utf-8") as f:
4955
lines = f.read().splitlines()
56+
lines_count = len(lines)
57+
line_id = 0
5058
for line in lines:
59+
line_id += 1
60+
loading_progress = round((line_id / lines_count) * 100)
61+
print(f"\rExtracting data: {str(loading_progress).zfill(2)}%", end="", flush=True)
5162
# Skip comment
5263
if line.startswith("#"):
5364
continue
@@ -64,31 +75,35 @@ def load_records(kms_data_file):
6475
results = re.findall(resource_type_regex, line, re.IGNORECASE)
6576
if len(results) > 0:
6677
resource_name = results[0]
67-
if resource_type not in records[k8s_ns][RESOURCE_KEY]:
68-
records[k8s_ns][RESOURCE_KEY][resource_type] = []
69-
if resource_name not in records[k8s_ns][RESOURCE_KEY][resource_type]:
70-
records[k8s_ns][RESOURCE_KEY][resource_type].append(resource_name)
78+
if is_name_not_none(resource_name):
79+
if resource_type not in records[k8s_ns][RESOURCE_KEY]:
80+
records[k8s_ns][RESOURCE_KEY][resource_type] = []
81+
if resource_name not in records[k8s_ns][RESOURCE_KEY][resource_type]:
82+
records[k8s_ns][RESOURCE_KEY][resource_type].append(resource_name)
7183
# Extract the other types of components
7284
for component_type in K8S_OTHERS_TYPES:
7385
component_type_regex = f"{component_type}=\"(.*?)\""
7486
results = re.findall(component_type_regex, line, re.IGNORECASE)
7587
if len(results) > 0:
7688
component_name = results[0]
77-
if component_type not in records[k8s_ns][OTHER_KEY]:
78-
records[k8s_ns][OTHER_KEY][component_type] = []
79-
if component_name not in records[k8s_ns][OTHER_KEY][component_type]:
80-
records[k8s_ns][OTHER_KEY][component_type].append(component_name)
89+
if is_name_not_none(component_name):
90+
if component_type not in records[k8s_ns][OTHER_KEY]:
91+
records[k8s_ns][OTHER_KEY][component_type] = []
92+
if component_name not in records[k8s_ns][OTHER_KEY][component_type]:
93+
records[k8s_ns][OTHER_KEY][component_type].append(component_name)
8194
# Extract special item like this one:
8295
# gotk_reconcile_duration_seconds_bucket{kind="Kustomization",name="workspace",namespace="kommander",le="2"}
83-
if 'kind=' in line and 'name=' in line:
96+
if "kind=" in line and "name=" in line:
8497
kind_regex = "kind=\"(.*?)\""
8598
kind_name = re.findall(kind_regex, line, re.IGNORECASE)[0]
86-
name_regex = "name=\"(.*?)\""
87-
name_name = re.findall(name_regex, line, re.IGNORECASE)[0]
88-
if kind_name not in records[k8s_ns][MISC_KEY]:
89-
records[k8s_ns][MISC_KEY][kind_name] = []
90-
if name_name not in records[k8s_ns][MISC_KEY][kind_name]:
91-
records[k8s_ns][MISC_KEY][kind_name].append(name_name)
99+
if kind_name.lower() not in (K8S_RESOURCE_TYPES + K8S_OTHERS_TYPES) and is_name_not_none(kind_name):
100+
name_regex = "name=\"(.*?)\""
101+
name_name = re.findall(name_regex, line, re.IGNORECASE)[0]
102+
if kind_name not in records[k8s_ns][MISC_KEY]:
103+
records[k8s_ns][MISC_KEY][kind_name] = []
104+
if name_name not in records[k8s_ns][MISC_KEY][kind_name]:
105+
records[k8s_ns][MISC_KEY][kind_name].append(name_name)
106+
print("\r", end="", flush=True)
92107
return collections.OrderedDict(sorted(records.items()))
93108

94109

@@ -100,12 +115,12 @@ def generate_tree_representation(records):
100115
for category in [RESOURCE_KEY, OTHER_KEY, MISC_KEY]:
101116
category_items = namespace_items[category]
102117
if len(category_items) > 0:
103-
print(colored(f"=> {category.capitalize()}", "light_cyan"))
118+
print(colored(f"=> {category.capitalize()}", "light_magenta"))
104119
for category_item_type in category_items:
105120
item_collection = category_items[category_item_type]
106121
item_count = len(item_collection)
107122
item_collection.sort()
108-
print(colored(f"==> {category_item_type.capitalize()} ({item_count}): ", "light_magenta"), end="")
123+
print(colored(f"==> {category_item_type.capitalize()} ({item_count}): ", "light_cyan"), end="")
109124
print(", ".join(item_collection))
110125

111126

0 commit comments

Comments
 (0)