86 lines
3 KiB
JavaScript
86 lines
3 KiB
JavaScript
import k8s from "@kubernetes/client-node";
|
|
import { getUserDeployments } from "./k8s-server-control.js";
|
|
import { getServerEntries } from "../database/queries/server-queries.js";
|
|
const kc = new k8s.KubeConfig();
|
|
kc.loadFromDefault();
|
|
|
|
const k8sMetrics = new k8s.Metrics(kc);
|
|
const namespace = process.env.MCL_SERVER_NAMESPACE;
|
|
|
|
function getServerMetrics(podMetricsRes, serverId, serverAvailable) {
|
|
const pod = podMetricsRes.items.find(({ metadata: md }) => {
|
|
return (
|
|
md.annotations &&
|
|
md.annotations["minecluster.dunemask.net/id"] === serverId
|
|
);
|
|
});
|
|
if (!serverAvailable || !pod) return null;
|
|
const podCpus = pod.containers.map(
|
|
({ usage }) => parseInt(usage.cpu) / 1_000_000,
|
|
);
|
|
const podMems = pod.containers.map(
|
|
({ usage }) => parseInt(usage.memory) / 1024,
|
|
);
|
|
return {
|
|
cpu: Math.ceil(podCpus.reduce((a, b) => a + b)),
|
|
memory: Math.ceil(podMems.reduce((a, b) => a + b)),
|
|
};
|
|
}
|
|
|
|
function getServerStatus(server) {
|
|
const { containers } = server.spec.template.spec;
|
|
const services = containers.map(({ name }) => name.split("-").pop());
|
|
const serverStatusList = server.status.conditions.map(
|
|
({ type: statusType, status: sts }) => ({ statusType, sts }),
|
|
);
|
|
const deploymentAvailable =
|
|
serverStatusList.find(
|
|
(ss) => ss.statusType === "Available" && ss.sts === "True",
|
|
) !== undefined;
|
|
const serverAvailable = services.includes(`server`) && deploymentAvailable;
|
|
const ftpAvailable = services.includes("ftp"); // TODO this needs some handling for container creation
|
|
return { serverAvailable, ftpAvailable, services, deploymentAvailable };
|
|
}
|
|
|
|
export async function getInstances(cairoId) {
|
|
const [serverDeployments, podMetricsRes, entries] = await Promise.all([
|
|
getUserDeployments(cairoId),
|
|
k8sMetrics.getPodMetrics(namespace),
|
|
getServerEntries(),
|
|
]);
|
|
|
|
var serverId, metrics;
|
|
const serverInstances = serverDeployments.map((s) => {
|
|
serverId = s.metadata.annotations["minecluster.dunemask.net/id"];
|
|
const entry = entries.find((e) => e.id === serverId);
|
|
const { ftpAvailable, serverAvailable, services, deploymentAvailable } =
|
|
getServerStatus(s);
|
|
metrics = getServerMetrics(podMetricsRes, serverId, serverAvailable);
|
|
return {
|
|
name: !!entry ? entry.name : "Unknown",
|
|
host: !!entry ? entry.host : "Unkonwn",
|
|
id: serverId,
|
|
metrics,
|
|
services,
|
|
serverAvailable,
|
|
ftpAvailable,
|
|
deploymentAvailable,
|
|
};
|
|
});
|
|
return serverInstances;
|
|
}
|
|
|
|
export async function getNamespaceMetrics() {
|
|
const serverInstances = await getInstances();
|
|
var clusterMetrics = { cpu: 0, memory: 0 };
|
|
if (servers.length > 1) {
|
|
const clusterCpu = serverInstances
|
|
.map(({ metrics }) => (metrics ? metrics.cpu : 0))
|
|
.reduce((a, b) => a + b);
|
|
const clusterMem = serverInstances
|
|
.map(({ metrics }) => (metrics ? metrics.memory : 0))
|
|
.reduce((a, b) => a + b);
|
|
clusterMetrics = { cpu: clusterCpu, memory: clusterMem };
|
|
}
|
|
return clusterMetrics;
|
|
}
|