minecluster/lib/controllers/sub-controllers/console-controller.js

68 lines
2.4 KiB
JavaScript

// Imports
import k8s from "@kubernetes/client-node";
import { Rcon as RconClient } from "rcon-client";
import stream from "stream";
import { ERR, WARN } from "../../util/logging.js";
import { getServerEntry } from "../../database/queries/server-queries.js";
// Kubernetes Configuration
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sCore = kc.makeApiClient(k8s.CoreV1Api);
const namespace = process.env.MCL_SERVER_NAMESPACE;
// Retrieves logs from the minecraft server container
export async function webConsoleLogs(socket) {
const { serverId } = socket.mcs;
const server = await getServerEntry(serverId);
const podName = `mcl-${server.mclName}`;
const containerName = `${podName}-server`;
const podResponse = await k8sCore.listNamespacedPod(namespace);
const pods = podResponse.body.items.map((vp1) => vp1.metadata.name);
const mcsPods = pods.filter((p) => p.startsWith(podName));
if (mcsPods.length === 0)
throw Error(`Could not find a pod that starts with ${podName}`);
if (mcsPods.length > 1)
throw Error(`Multiple pods match the name ${podName}`);
const log = new k8s.Log(kc);
const logStream = new stream.PassThrough();
logStream.on("data", (chunk) =>
socket.emit("push", Buffer.from(chunk).toString()),
);
log
.log(namespace, mcsPods[0], containerName, logStream, {
follow: true,
pretty: false,
timestamps: false,
})
.catch((e) => ERR("CONSOLE CONTROLLER", "Error streaming logs", e));
}
// Creates an RCON connection to the minecraft container
export async function webConsoleRcon(socket) {
if (socket.rconClient)
return VERB("RCON", "Socket already connected to RCON");
const { serverId } = socket.mcs;
const server = await getServerEntry(serverId);
const rconSecret = `mcl-${server.mclName}-rcon-secret`;
const rconRes = await k8sCore.readNamespacedSecret(rconSecret, namespace);
const rconPassword = Buffer.from(
rconRes.body.data["rcon-password"],
"base64",
).toString("utf8");
const rconHost = `mcl-${server.mclName}-rcon.${namespace}.svc.cluster.local`;
const rcon = new RconClient({
host: rconHost,
port: 25575,
password: rconPassword,
});
rcon.on("error", (error) => socket.emit("push", error));
try {
await rcon.connect();
} catch (error) {
socket.emit("rcon-error", "Could not connect RCON Input to server!");
WARN("RCON", `Could not connect to '${rconHost}'`);
}
socket.rconClient = rcon;
}