58 lines
2.6 KiB
TypeScript
58 lines
2.6 KiB
TypeScript
import { existsSync, readFileSync } from "node:fs";
|
|
import { isAbsolute, join } from "node:path";
|
|
import { rootPath } from "./config";
|
|
|
|
const hostK8sConfigPath = "config/unidesk-host-k8s.yaml";
|
|
|
|
function asRecord(value: unknown, path: string): Record<string, unknown> {
|
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${path} must be an object`);
|
|
return value as Record<string, unknown>;
|
|
}
|
|
|
|
function stringField(obj: Record<string, unknown>, key: string, path: string): string {
|
|
const value = obj[key];
|
|
if (typeof value !== "string" || value.length === 0) throw new Error(`${path}.${key} must be a non-empty string`);
|
|
return value;
|
|
}
|
|
|
|
function readEnvFile(path: string): Record<string, string> {
|
|
const values: Record<string, string> = {};
|
|
const text = readFileSync(path, "utf8");
|
|
for (const [index, rawLine] of text.split(/\r?\n/u).entries()) {
|
|
const line = rawLine.trim();
|
|
if (line.length === 0 || line.startsWith("#")) continue;
|
|
const eq = line.indexOf("=");
|
|
if (eq <= 0) throw new Error(`${path}:${index + 1} must be KEY=value`);
|
|
values[line.slice(0, eq)] = line.slice(eq + 1);
|
|
}
|
|
return values;
|
|
}
|
|
|
|
function readHostK8sConfig(): Record<string, unknown> | null {
|
|
const path = rootPath(hostK8sConfigPath);
|
|
if (!existsSync(path)) return null;
|
|
return asRecord(Bun.YAML.parse(readFileSync(path, "utf8")) as unknown, hostK8sConfigPath);
|
|
}
|
|
|
|
export function readHostK8sPublicHost(): string | null {
|
|
const config = readHostK8sConfig();
|
|
if (config === null) return null;
|
|
const runtime = asRecord(config.runtime, `${hostK8sConfigPath}.runtime`);
|
|
return stringField(runtime, "publicHost", `${hostK8sConfigPath}.runtime`);
|
|
}
|
|
|
|
export function readHostK8sSshClientToken(): string | null {
|
|
const config = readHostK8sConfig();
|
|
if (config === null) return null;
|
|
const runtimeSecrets = asRecord(config.runtimeSecrets, `${hostK8sConfigPath}.runtimeSecrets`);
|
|
const sourceRef = asRecord(runtimeSecrets.sourceRef, `${hostK8sConfigPath}.runtimeSecrets.sourceRef`);
|
|
const target = asRecord(runtimeSecrets.target, `${hostK8sConfigPath}.runtimeSecrets.target`);
|
|
const keys = asRecord(target.keys, `${hostK8sConfigPath}.runtimeSecrets.target.keys`);
|
|
const sourcePathRaw = stringField(sourceRef, "path", `${hostK8sConfigPath}.runtimeSecrets.sourceRef`);
|
|
const tokenKey = stringField(keys, "sshClientToken", `${hostK8sConfigPath}.runtimeSecrets.target.keys`);
|
|
const sourcePath = isAbsolute(sourcePathRaw) ? sourcePathRaw : join(rootPath(), sourcePathRaw);
|
|
if (!existsSync(sourcePath)) return null;
|
|
const token = readEnvFile(sourcePath)[tokenKey]?.trim() ?? "";
|
|
return token.length > 0 ? token : null;
|
|
}
|