backend/src/main/java/dev/dinauer/NodeResource.java

112 lines
3.7 KiB
Java

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 io.smallrye.common.annotation.Blocking;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
@Path("/nodes")
@ApplicationScoped
@Blocking
@Authenticated
public class NodeResource
{
private static final Logger LOG = LoggerFactory.getLogger(NodeResource.class);
@Inject
ClientProvider clientProvider;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<NodeStats> getMonitoring() throws IOException, InterruptedException
{
List<NodeStats> result = new ArrayList<>();
List<String> 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<String> getTopNodes() throws IOException, InterruptedException
{
List<String> commands = List.of("kubectl", String.format("--kubeconfig=%s", clientProvider.pathToKubeconfig()), "top", "nodes", "--no-headers");
LOG.info("Executing command: {}", String.join(" ", commands));
ProcessBuilder pb = new ProcessBuilder(commands);
Process p = pb.start();
List<String> text = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())))
{
String line;
while((line = br.readLine()) != null)
{
text.add(line);
}
}
int exitCode = p.waitFor();
if(exitCode == 0)
{
LOG.info("Found {} nodes", text.size());
return text;
}
throw new RuntimeException("Failed to retrieve top nodes.");
}
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);
}
}