From 182b9c8a2be602b9eba02ce32ae5ed350c305e2c Mon Sep 17 00:00:00 2001 From: Aleksandr Tcitlionok <803797+terghalin@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:34:47 +0000 Subject: [PATCH] update(pseudo): add namespace and conversions --- app/extras/pseudographic.py | 80 +++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/app/extras/pseudographic.py b/app/extras/pseudographic.py index d479fe9..5d87eec 100644 --- a/app/extras/pseudographic.py +++ b/app/extras/pseudographic.py @@ -1,9 +1,33 @@ -# Show pseudo-graphic tables using rich library, if there is no frontend from rich.console import Console from rich.table import Table from database import fetch_all from kubernetes import client, config +# Helper functions for conversions +def convert_cpu_to_cores(cpu): + """ + Convert CPU usage to cores for human-readable format. + """ + if "n" in cpu: # Nanocores to cores + return round(int(cpu.replace("n", "")) / 1e9, 4) + elif "u" in cpu: # Microcores to cores + return round(int(cpu.replace("u", "")) / 1e6, 4) + elif "m" in cpu: # Millicores to cores + return round(int(cpu.replace("m", "")) / 1000, 4) + return float(cpu) # Already in cores + +def convert_memory_to_mib(memory): + """ + Convert memory to MiB (mebibytes). + """ + if "Ki" in memory: + return int(memory.replace("Ki", "")) / 1024 + elif "Mi" in memory: + return int(memory.replace("Mi", "")) + elif "Gi" in memory: + return int(memory.replace("Gi", "")) * 1024 + return float(memory) + def display_metal_nodes(): console = Console() table = Table(title="Metal Nodes") @@ -44,17 +68,6 @@ def display_virtual_machines(): console.print(table) -def kib_to_gib(kib_value): - """ - Convert memory from Ki (kibibytes) to GiB (gibibytes). - """ - try: - kib = int(kib_value[:-2]) - gib = kib / 1024 / 1024 - return f"{gib:.2f} GiB" - except ValueError: - return kib_value # Return original if conversion fails - def display_kubernetes_nodes(): console = Console() config.load_incluster_config() @@ -63,7 +76,7 @@ def display_kubernetes_nodes(): table = Table(title="Kubernetes Nodes") table.add_column("Node Name") table.add_column("CPU", justify="right") - table.add_column("Memory", justify="right") + table.add_column("Memory (MiB)", justify="right") table.add_column("Pods Allocatable", justify="right") nodes = v1.list_node() @@ -71,17 +84,50 @@ def display_kubernetes_nodes(): table.add_row( node.metadata.name, node.status.capacity.get("cpu"), - kib_to_gib(node.status.capacity.get("memory")), + str(round(convert_memory_to_mib(node.status.capacity.get("memory")), 2)), node.status.allocatable.get("pods") ) console.print(table) - console.print("\n[bold]Namespaces:[/bold]") - namespaces = [ns.metadata.name for ns in v1.list_namespace().items] - console.print(", ".join(namespaces)) +def display_namespace_usage(): + console = Console() + config.load_incluster_config() + metrics_client = client.CustomObjectsApi() + + table = Table(title="Namespace Resource Usage") + table.add_column("Namespace") + table.add_column("CPU (Cores)", justify="right") + table.add_column("Memory (MiB)", justify="right") + + namespace_usage = {} + pod_metrics = metrics_client.list_cluster_custom_object( + group="metrics.k8s.io", version="v1beta1", plural="pods" + ) + + for pod in pod_metrics["items"]: + namespace = pod["metadata"]["namespace"] + if namespace not in namespace_usage: + namespace_usage[namespace] = {"cpu": 0, "memory": 0} + + for container in pod["containers"]: + cpu_usage = container["usage"]["cpu"] + memory_usage = container["usage"]["memory"] + + namespace_usage[namespace]["cpu"] += convert_cpu_to_cores(cpu_usage) + namespace_usage[namespace]["memory"] += convert_memory_to_mib(memory_usage) + + for namespace, usage in namespace_usage.items(): + table.add_row( + namespace, + f"{round(usage['cpu'], 4)}", + f"{round(usage['memory'], 2)}" + ) + + console.print(table) if __name__ == "__main__": display_metal_nodes() display_virtual_machines() display_kubernetes_nodes() + display_namespace_usage()