78 lines
2.9 KiB
TypeScript
78 lines
2.9 KiB
TypeScript
import type { IUptimeRunnerConfig } from './interfaces.ts';
|
|
|
|
export const DEFAULT_CONFIG_PATH = '/etc/uptimerunner/config.json';
|
|
|
|
export async function loadConfig(configPathArg = getConfigPath()): Promise<IUptimeRunnerConfig> {
|
|
const fileConfig = await readConfigFile(configPathArg);
|
|
const config = applyEnvironmentOverrides(fileConfig);
|
|
validateConfig(config);
|
|
return config;
|
|
}
|
|
|
|
export async function writeConfig(
|
|
configArg: IUptimeRunnerConfig,
|
|
configPathArg = getConfigPath(),
|
|
): Promise<void> {
|
|
validateConfig(configArg);
|
|
const configDir = configPathArg.slice(0, configPathArg.lastIndexOf('/')) || '.';
|
|
await Deno.mkdir(configDir, { recursive: true });
|
|
await Deno.writeTextFile(`${configPathArg}.tmp`, `${JSON.stringify(configArg, null, 2)}\n`);
|
|
await Deno.rename(`${configPathArg}.tmp`, configPathArg);
|
|
}
|
|
|
|
export function getConfigPath(): string {
|
|
return Deno.env.get('UPTIMERUNNER_CONFIG') || DEFAULT_CONFIG_PATH;
|
|
}
|
|
|
|
export function applyEnvironmentOverrides(configArg: Partial<IUptimeRunnerConfig>) {
|
|
const labels = Deno.env.get('UPTIMERUNNER_LABELS');
|
|
const pollIntervalMs = Deno.env.get('UPTIMERUNNER_POLL_INTERVAL_MS');
|
|
const maxConcurrentChecks = Deno.env.get('UPTIMERUNNER_MAX_CONCURRENT_CHECKS');
|
|
|
|
return {
|
|
...configArg,
|
|
instanceUrl: Deno.env.get('UPTIMERUNNER_INSTANCE_URL') || configArg.instanceUrl,
|
|
runnerId: Deno.env.get('UPTIMERUNNER_RUNNER_ID') || configArg.runnerId,
|
|
token: Deno.env.get('UPTIMERUNNER_TOKEN') || configArg.token,
|
|
labels: labels
|
|
? labels.split(',').map((labelArg) => labelArg.trim()).filter(Boolean)
|
|
: configArg.labels,
|
|
pollIntervalMs: pollIntervalMs ? Number(pollIntervalMs) : configArg.pollIntervalMs,
|
|
maxConcurrentChecks: maxConcurrentChecks
|
|
? Number(maxConcurrentChecks)
|
|
: configArg.maxConcurrentChecks,
|
|
} satisfies Partial<IUptimeRunnerConfig>;
|
|
}
|
|
|
|
export function validateConfig(
|
|
configArg: Partial<IUptimeRunnerConfig>,
|
|
): asserts configArg is IUptimeRunnerConfig {
|
|
if (!configArg.instanceUrl) {
|
|
throw new Error('Missing instanceUrl. Set it in config or UPTIMERUNNER_INSTANCE_URL.');
|
|
}
|
|
if (!configArg.runnerId) {
|
|
throw new Error('Missing runnerId. Set it in config or UPTIMERUNNER_RUNNER_ID.');
|
|
}
|
|
if (!configArg.token) {
|
|
throw new Error('Missing token. Set it in config or UPTIMERUNNER_TOKEN.');
|
|
}
|
|
if (configArg.pollIntervalMs !== undefined && configArg.pollIntervalMs < 1000) {
|
|
throw new Error('pollIntervalMs must be at least 1000ms.');
|
|
}
|
|
if (configArg.maxConcurrentChecks !== undefined && configArg.maxConcurrentChecks < 1) {
|
|
throw new Error('maxConcurrentChecks must be at least 1.');
|
|
}
|
|
}
|
|
|
|
async function readConfigFile(configPathArg: string): Promise<Partial<IUptimeRunnerConfig>> {
|
|
try {
|
|
const configText = await Deno.readTextFile(configPathArg);
|
|
return JSON.parse(configText) as Partial<IUptimeRunnerConfig>;
|
|
} catch (error) {
|
|
if (error instanceof Deno.errors.NotFound) {
|
|
return {};
|
|
}
|
|
throw error;
|
|
}
|
|
}
|