2023-03-15 15:20:08 +00:00
|
|
|
import k8s from "@kubernetes/client-node";
|
2023-12-22 14:45:49 -07:00
|
|
|
import { getDeployments } from "./k8s-server-control.js";
|
2023-03-15 15:20:08 +00:00
|
|
|
const kc = new k8s.KubeConfig();
|
|
|
|
kc.loadFromDefault();
|
|
|
|
|
|
|
|
const k8sMetrics = new k8s.Metrics(kc);
|
|
|
|
const namespace = process.env.MCL_SERVER_NAMESPACE;
|
|
|
|
|
2023-12-22 14:45:49 -07:00
|
|
|
function getServerMetrics(podMetricsRes, serverId, serverAvailable) {
|
|
|
|
const pod = podMetricsRes.items.find(({ metadata: md }) => {
|
|
|
|
return (
|
|
|
|
md.annotations &&
|
|
|
|
md.annotations["minecluster.dunemask.net/id"] === serverId
|
|
|
|
);
|
|
|
|
});
|
2023-03-15 15:20:08 +00:00
|
|
|
|
2023-12-22 14:45:49 -07:00
|
|
|
if (serverAvailable && pod) {
|
|
|
|
const podCpus = pod.containers.map(
|
|
|
|
({ usage }) => parseInt(usage.cpu) / 1_000_000,
|
|
|
|
);
|
|
|
|
const podMems = pod.containers.map(
|
|
|
|
({ usage }) => parseInt(usage.memory) / 1024,
|
|
|
|
);
|
|
|
|
metrics = {
|
|
|
|
cpu: Math.ceil(podCpus.reduce((a, b) => a + b)),
|
|
|
|
memory: Math.ceil(podMems.reduce((a, b) => a + b)),
|
|
|
|
};
|
2023-12-20 03:20:04 +00:00
|
|
|
}
|
2023-03-15 15:20:08 +00:00
|
|
|
}
|
|
|
|
|
2023-12-20 03:20:04 +00:00
|
|
|
export async function getInstances() {
|
|
|
|
const serverDeployments = await getDeployments();
|
2023-12-22 14:45:49 -07:00
|
|
|
const podMetricsRes = await k8sMetrics.getPodMetrics(namespace);
|
|
|
|
var name, serverId, metrics, services, serverAvailable, ftpAvailable;
|
2023-12-20 03:20:04 +00:00
|
|
|
const serverInstances = serverDeployments.map((s) => {
|
2023-12-22 14:45:49 -07:00
|
|
|
serverId = s.metadata.annotations["minecluster.dunemask.net/id"];
|
|
|
|
name = s.metadata.name;
|
2023-03-15 15:20:08 +00:00
|
|
|
metrics = null;
|
2023-12-22 14:45:49 -07:00
|
|
|
|
2023-12-22 18:30:48 +00:00
|
|
|
const { containers } = s.spec.template.spec;
|
|
|
|
services = containers.map(({ name }) => name.split("-").pop());
|
|
|
|
const serverStatusList = s.status.conditions.map(
|
|
|
|
({ type: statusType, status: sts }) => ({ statusType, sts }),
|
2023-12-20 03:20:04 +00:00
|
|
|
);
|
2023-12-22 18:30:48 +00:00
|
|
|
const deploymentAvailable =
|
|
|
|
serverStatusList.find(
|
|
|
|
(ss) => ss.statusType === "Available" && ss.sts === "True",
|
|
|
|
) !== undefined;
|
|
|
|
serverAvailable = services.includes(`server`) && deploymentAvailable;
|
|
|
|
ftpAvailable = services.includes("ftp") && deploymentAvailable;
|
2023-12-22 14:45:49 -07:00
|
|
|
metrics = getServerMetrics(podMetricsRes, serverId, serverAvailable);
|
|
|
|
return {
|
|
|
|
name,
|
|
|
|
id: serverId,
|
|
|
|
metrics,
|
|
|
|
services,
|
|
|
|
serverAvailable,
|
|
|
|
ftpAvailable,
|
|
|
|
};
|
2023-03-15 15:20:08 +00:00
|
|
|
});
|
2023-12-20 03:20:04 +00:00
|
|
|
return serverInstances;
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function getNamespaceMetrics() {
|
|
|
|
const serverInstances = await getInstances();
|
2023-03-15 15:20:08 +00:00
|
|
|
var clusterMetrics = { cpu: 0, memory: 0 };
|
|
|
|
if (servers.length > 1) {
|
2023-12-20 03:20:04 +00:00
|
|
|
const clusterCpu = serverInstances
|
2023-03-15 15:20:08 +00:00
|
|
|
.map(({ metrics }) => (metrics ? metrics.cpu : 0))
|
|
|
|
.reduce((a, b) => a + b);
|
2023-12-20 03:20:04 +00:00
|
|
|
const clusterMem = serverInstances
|
2023-03-15 15:20:08 +00:00
|
|
|
.map(({ metrics }) => (metrics ? metrics.memory : 0))
|
|
|
|
.reduce((a, b) => a + b);
|
|
|
|
clusterMetrics = { cpu: clusterCpu, memory: clusterMem };
|
|
|
|
}
|
2023-12-20 03:20:04 +00:00
|
|
|
return clusterMetrics;
|
2023-03-15 15:20:08 +00:00
|
|
|
}
|