
Co-authored-by: Dunemask <dunemask@gmail.com> Reviewed-on: https://gitea.dunemask.dev/elysium/minecluster/pulls/7
97 lines
2.8 KiB
JavaScript
97 lines
2.8 KiB
JavaScript
import ftp from "basic-ftp";
|
|
import { ERR } from "../util/logging.js";
|
|
import { getServerAssets } from "./k8s-server-control.js";
|
|
import ExpressClientError from "../util/ExpressClientError.js";
|
|
import { Readable, Writable, Transform } from "node:stream";
|
|
|
|
const namespace = process.env.MCL_SERVER_NAMESPACE;
|
|
|
|
const pathSecurityCheck = (path) => {
|
|
if (!path.startsWith("."))
|
|
throw new ExpressClientError({
|
|
m: "Only relative directories can be created",
|
|
c: 409,
|
|
});
|
|
};
|
|
|
|
const handleError = (e) => {
|
|
ERR("SERVER FILES", "Error occurred while preforming FTP operation!", e);
|
|
throw new ExpressClientError({
|
|
c: 500,
|
|
m: "Error occurred while performing FTP operation!",
|
|
});
|
|
};
|
|
|
|
export async function getFtpClient(serverService) {
|
|
const { name } = serverService.metadata;
|
|
const client = new ftp.Client();
|
|
await client.access({
|
|
host: `${name}.${namespace}.svc.cluster.local`,
|
|
user: "minecluster",
|
|
password: "minecluster",
|
|
});
|
|
return client;
|
|
}
|
|
|
|
export async function useServerFtp(serverSpec, fn) {
|
|
const { id } = serverSpec;
|
|
const server = await getServerAssets(id);
|
|
if (!server)
|
|
throw new ExpressClientError({
|
|
c: 404,
|
|
m: "No resources for that server were found!",
|
|
});
|
|
if (!server.service)
|
|
throw new ExpressClientError({
|
|
c: 409,
|
|
m: "Service doesn't exist, please contact your hosting provider!",
|
|
});
|
|
const client = await getFtpClient(server.service);
|
|
const result = await fn(client);
|
|
client.close();
|
|
return result;
|
|
}
|
|
|
|
export async function listServerFiles(serverSpec) {
|
|
const { path } = serverSpec;
|
|
const files = useServerFtp(serverSpec, async (c) => await c.list(path)).catch(
|
|
handleError,
|
|
);
|
|
return files;
|
|
}
|
|
|
|
export async function createServerFolder(serverSpec) {
|
|
const { path } = serverSpec;
|
|
pathSecurityCheck(path);
|
|
await useServerFtp(serverSpec, async (c) => c.ensureDir(path)).catch(
|
|
handleError,
|
|
);
|
|
}
|
|
|
|
export async function removeServerItem(serverSpec) {
|
|
const { path, isDir } = serverSpec;
|
|
pathSecurityCheck(path);
|
|
await useServerFtp(serverSpec, async (c) => {
|
|
if (isDir) await c.removeDir(path);
|
|
else await c.remove(path);
|
|
}).catch(handleError);
|
|
}
|
|
|
|
export async function uploadServerItem(serverSpec, file) {
|
|
const fileStream = Readable.from(file.buffer);
|
|
const { path } = serverSpec;
|
|
pathSecurityCheck(path);
|
|
await useServerFtp(serverSpec, async (c) => {
|
|
await c.uploadFrom(fileStream, path);
|
|
}).catch(handleError);
|
|
}
|
|
|
|
export async function getServerItem(serverSpec, writableStream) {
|
|
const { path } = serverSpec;
|
|
const ds = new Transform({ transform: (c, e, cb) => cb(null, c) });
|
|
pathSecurityCheck(path);
|
|
const ftpTransfer = useServerFtp(serverSpec, async (c) => {
|
|
await c.downloadTo(ds, path);
|
|
}).catch(handleError);
|
|
return { ds, ftpTransfer };
|
|
}
|