package dev.dinauer; import dev.dinauer.utils.ClientProvider; import io.fabric8.kubernetes.api.model.Node; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.quarkus.security.Authenticated; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; @Path("/nodes") @ApplicationScoped @Authenticated public class NodeResource { @Inject ClientProvider clientProvider; @GET @Produces(MediaType.APPLICATION_JSON) public List getMonitoring() throws IOException, InterruptedException { List result = new ArrayList<>(); List stats = getTopNodes(); for(String nodeName : stats) { String[] parts = nodeName.split("\\s+"); if(parts.length == 5) { String name = parts[0]; Node node = clientProvider.getClient().nodes().withName(name).get(); Integer absoluteCpu = extractInteger(parts[1]); Integer relativeCpu = extractInteger(parts[2]); Integer absoluteMemory = extractMemory(parts[3]); Integer relativeMemory = extractInteger(parts[4]); result.add(new NodeStats(node, absoluteCpu, relativeCpu, Integer.parseInt(node.getStatus().getAllocatable().get("cpu").getAmount()) * 1000, absoluteMemory, relativeMemory, extractMemory(node.getStatus().getAllocatable().get("memory").getAmount()))); } } return result; } private List getTopNodes() throws IOException, InterruptedException { ProcessBuilder pb = new ProcessBuilder(List.of("kubectl", "top", "nodes", "--no-headers")); Process p = pb.start(); List text = new ArrayList<>(); try(BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) { String line; while((line = br.readLine()) != null) { text.add(line); } } p.waitFor(); return text; } public record NodeStats(Node node, Integer absoluteCpuUsage, Integer relativeCpuUsage, Integer totalCpu, Integer absoluteMemory, Integer relativeMemory, Integer totalMemory) { } private Integer extractInteger(String input) { return Integer.valueOf(input.replace("m", "").replace("%", "")); } private Integer extractMemory(String input) { if(input.contains("Ki")) { return Integer.parseInt(input.replace("Ki", "")); } if(input.contains("Mi")) { return Integer.parseInt(input.replace("Mi", "")) * 1024; } if(input.contains("Gi")) { return Integer.parseInt(input.replace("Gi", "")) * 1024 * 1024; } return Integer.parseInt(input); } }