112 lines
3.7 KiB
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);
|
|
}
|
|
}
|