cloudmon/monitor/views.py
2026-11-01 06:39:17 -06:00

84 lines
4.4 KiB
Python

import requests
from django.http import JsonResponse
from django.views.generic import TemplateView, View
class DashboardView(TemplateView):
template_name = "monitor/dashboard.html"
class ClusterGraphDataView(View):
def get(self, request, *args, **kwargs):
# Holt den State direkt aus deinem Forgejo-HTTP-Backend
forgejo_url = "http://forgejo:3000/api/v1/repos/bast/boday_tf/terraform/state/sandbox"
headers = {"Authorization": "token z6xlwg3dSRYZ59zUxfrztDJasG6VkvulFyTwtJQS"}
try:
response = requests.get(forgejo_url, headers=headers, timeout=5)
if response.status_code != 200:
return JsonResponse({"error": "Terraform State konnte nicht geladen werden"}, status=response.status_code)
state_json = response.json()
resources = state_json.get("resources", [])
ingresses = []
services = {}
deployments = {}
# Flache Terraform-Struktur filtern
for res in resources:
res_type = res.get("type")
res_name = res.get("name")
instances = res.get("instances", [])
if not instances: continue
# act/gitea liefert instanzen als Liste
if isinstance(instances, list) and len(instances) > 0:
attributes = instances[0].get("attributes", {})
else:
attributes = instances.get("attributes", {})
if res_type == "kubernetes_ingress_v1":
ingresses.append({
"name": attributes.get("metadata", [{}])[0].get("name", res_name) if isinstance(attributes.get("metadata"), list) else attributes.get("metadata", {}).get("name", res_name),
"rules": attributes.get("spec", [{}])[0].get("rule", []) if isinstance(attributes.get("spec"), list) else attributes.get("spec", {}).get("rule", [])
})
elif res_type == "kubernetes_service" or res_type == "kubernetes_service_v1":
svc_actual_name = attributes.get("metadata", [{}])[0].get("name", res_name) if isinstance(attributes.get("metadata"), list) else attributes.get("metadata", {}).get("name", res_name)
services[svc_actual_name] = {"name": svc_actual_name, "type": "Service"}
elif res_type == "kubernetes_deployment" or res_type == "kubernetes_deployment_v1":
dep_actual_name = attributes.get("metadata", [{}])[0].get("name", res_name) if isinstance(attributes.get("metadata"), list) else attributes.get("metadata", {}).get("name", res_name)
deployments[dep_actual_name] = {"name": dep_actual_name, "type": "Deployment"}
# D3.js Baumhierarchie aufbauen
root_node = {
"name": "Forgejo Control Plane",
"type": "Root",
"children": []
}
for ing in ingresses:
ing_node = {"name": ing["name"], "type": "Ingress", "children": []}
for rule in ing["rules"]:
http_paths = rule.get("http", [{}])[0].get("path", []) if isinstance(rule.get("http"), list) else rule.get("http", {}).get("path", [])
for path in http_paths:
backend_svc = path.get("backend", [{}])[0].get("service", [{}])[0].get("name") if isinstance(path.get("backend"), list) else path.get("backend", {}).get("service", {}).get("name")
if backend_svc in services:
svc_node = {"name": backend_svc, "type": "Service", "children": []}
for dep_name in deployments.keys():
if dep_name in backend_svc or backend_svc in dep_name:
svc_node["children"].append({
"name": dep_name,
"type": "Deployment",
"children": []
})
ing_node["children"].append(svc_node)
root_node["children"].append(ing_node)
return JsonResponse(root_node)
except Exception as e:
return JsonResponse({"error": str(e)}, status=500)