All checks were successful
farmcontrol/farmcontrol-server/pipeline/head This commit looks good
- Refactor commandline.js to improve server status checks and OTP authentication handling. - Introduce new functions for checking server status, printing server information, and setting log levels. - Add support for command line flags to manage log levels and server information display. - Implement logging level management in localserver.js, allowing dynamic log level adjustments via API. - Create a new logging.js module to centralize log level validation and application. - Update commandlineutils.js to include utility functions for flag handling and improved CLI output.
260 lines
6.6 KiB
JavaScript
260 lines
6.6 KiB
JavaScript
import {
|
|
authenticateWithOtp,
|
|
checkRunning,
|
|
getFlagValue,
|
|
hasFlag,
|
|
printAuthCommand,
|
|
printerHostInfo,
|
|
setLogLevel,
|
|
startWaiting,
|
|
stopWaiting,
|
|
} from "./commandlineutils.js";
|
|
import { VALID_LOG_LEVELS } from "./logging.js";
|
|
import chalk from "chalk";
|
|
|
|
async function getRunningServer(cli, logger) {
|
|
try {
|
|
startWaiting("Checking if Farm Control Server is running...", logger);
|
|
const runningServer = await checkRunning();
|
|
await stopWaiting();
|
|
return runningServer;
|
|
} catch (err) {
|
|
await stopWaiting();
|
|
cli.failure("Failed to check if Farm Control Server is running:", err);
|
|
cli.blank();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function checkServerRunning(cli, logger) {
|
|
const runningServer = await getRunningServer(cli, logger);
|
|
if (runningServer == false) {
|
|
cli.failure("Farm Control Server is not running.");
|
|
cli.blank();
|
|
return false;
|
|
}
|
|
if (runningServer == null) {
|
|
return false;
|
|
}
|
|
cli.success("Farm Control Server is running.");
|
|
return runningServer;
|
|
}
|
|
|
|
function printServerInfo(cli, runningServer) {
|
|
const buildNumber = runningServer.buildNumber ?? runningServer.build ?? "n/a";
|
|
cli.blank();
|
|
cli.sectionHeader("FarmControl Server");
|
|
cli.label(
|
|
"Version:",
|
|
runningServer.version ? `v${runningServer.version}` : "n/a",
|
|
);
|
|
cli.label("Build:", buildNumber === "dev" ? "dev" : `b${buildNumber}`);
|
|
cli.label("Config:", runningServer.configPath || "n/a");
|
|
cli.label("Data Dir:", runningServer.dataDir || "n/a");
|
|
cli.label("Connected:", cli.yesNo(runningServer.connected == true));
|
|
cli.label("Authenticated:", cli.yesNo(runningServer.authenticated == true));
|
|
cli.sectionFooter();
|
|
cli.blank();
|
|
|
|
if (runningServer.authenticated == false && runningServer.connected == true) {
|
|
cli.sectionHeader("Authenticate");
|
|
printAuthCommand(cli);
|
|
cli.sectionFooter();
|
|
} else if (
|
|
runningServer.connected == true &&
|
|
runningServer.authenticated == true
|
|
) {
|
|
cli.sectionHeader("Host");
|
|
printerHostInfo(runningServer.host, cli);
|
|
cli.sectionFooter();
|
|
}
|
|
|
|
cli.blank();
|
|
}
|
|
|
|
function printHelp(cli) {
|
|
cli.sectionHeader("Help");
|
|
cli.label(
|
|
chalk.bold.white("Usage: ") +
|
|
chalk.bold.cyanBright("farmcontrol-server ") +
|
|
chalk.white.dim("[options]"),
|
|
);
|
|
cli.sectionFooter();
|
|
const optionsPadding = " ".repeat(9);
|
|
cli.label(
|
|
chalk.bold.white("Options: ") +
|
|
chalk.bold.magentaBright("--info") +
|
|
" Outputs server information",
|
|
);
|
|
cli.label(
|
|
optionsPadding +
|
|
chalk.bold.magentaBright("--logLevel") +
|
|
" " +
|
|
chalk.dim("<level>") +
|
|
" Sets log level (" +
|
|
chalk.bold.cyan("trace") +
|
|
", " +
|
|
chalk.bold.blue("debug") +
|
|
", " +
|
|
chalk.bold.green("info") +
|
|
", " +
|
|
chalk.bold.yellow("warn") +
|
|
", " +
|
|
chalk.bold.red("error") +
|
|
")",
|
|
);
|
|
cli.label(
|
|
optionsPadding +
|
|
chalk.bold.magentaBright("--otp") +
|
|
" " +
|
|
chalk.dim("<otp>") +
|
|
" Authenticates with OTP",
|
|
);
|
|
cli.sectionFooter();
|
|
cli.blank();
|
|
}
|
|
|
|
async function runOtpCommand(cli, logger, otpCode) {
|
|
cli.blank();
|
|
|
|
if (otpCode == undefined) {
|
|
cli.failure("OTP code is required.");
|
|
cli.blank();
|
|
return { handled: true, result: false };
|
|
}
|
|
|
|
if (!/^\d{6}$/.test(String(otpCode))) {
|
|
cli.failure("OTP code must be a 6-digit number.");
|
|
cli.blank();
|
|
return { handled: true, result: false };
|
|
}
|
|
|
|
startWaiting("Authenticating with OTP...", logger);
|
|
let authenticatedServer;
|
|
try {
|
|
authenticatedServer = await authenticateWithOtp(otpCode);
|
|
await stopWaiting();
|
|
} catch (err) {
|
|
await stopWaiting();
|
|
throw err;
|
|
}
|
|
|
|
if (authenticatedServer.valid == false) {
|
|
cli.failure("Failed to authenticate!");
|
|
cli.failure(authenticatedServer.error);
|
|
cli.blank();
|
|
return authenticatedServer;
|
|
}
|
|
|
|
cli.success("Authenticated with OTP.");
|
|
cli.blank();
|
|
cli.sectionHeader("Host");
|
|
printerHostInfo(authenticatedServer.host, cli);
|
|
cli.sectionFooter();
|
|
cli.blank();
|
|
return authenticatedServer;
|
|
}
|
|
|
|
async function runLogLevelCommand(cli, logger, level) {
|
|
cli.blank();
|
|
|
|
if (level == undefined) {
|
|
cli.failure("Log level is required.");
|
|
cli.blank();
|
|
return { handled: true, result: false };
|
|
}
|
|
|
|
const normalized = String(level).toLowerCase();
|
|
if (!VALID_LOG_LEVELS.includes(normalized)) {
|
|
cli.failure(
|
|
`Invalid log level. Must be one of: ${VALID_LOG_LEVELS.join(", ")}`,
|
|
);
|
|
cli.blank();
|
|
return { handled: true, result: false };
|
|
}
|
|
|
|
startWaiting("Setting log level...", logger);
|
|
let result;
|
|
try {
|
|
result = await setLogLevel(normalized);
|
|
await stopWaiting();
|
|
} catch (err) {
|
|
await stopWaiting();
|
|
throw err;
|
|
}
|
|
|
|
if (result.valid == false) {
|
|
cli.failure("Failed to set log level!");
|
|
cli.failure(result.error);
|
|
cli.blank();
|
|
return result;
|
|
}
|
|
|
|
cli.success(`Log level set to ${result.logLevel}.`);
|
|
cli.blank();
|
|
return result;
|
|
}
|
|
|
|
const commands = [
|
|
{
|
|
matches: () => hasFlag("info"),
|
|
run: async ({ cli, logger }) => {
|
|
const runningServer = await checkServerRunning(cli, logger);
|
|
if (runningServer == false) {
|
|
return { handled: true, result: false };
|
|
}
|
|
printServerInfo(cli, runningServer);
|
|
return { handled: true, result: true };
|
|
},
|
|
},
|
|
{
|
|
matches: () => hasFlag("help") || hasFlag("h"),
|
|
run: async ({ cli }) => {
|
|
printHelp(cli);
|
|
return true;
|
|
},
|
|
},
|
|
{
|
|
matches: () =>
|
|
getFlagValue("logLevel") != undefined || hasFlag("logLevel"),
|
|
run: async ({ cli, logger }) => {
|
|
const runningServer = await checkServerRunning(cli, logger);
|
|
if (runningServer == false) {
|
|
return { handled: true, result: false };
|
|
}
|
|
const result = await runLogLevelCommand(
|
|
cli,
|
|
logger,
|
|
getFlagValue("logLevel"),
|
|
);
|
|
return { handled: true, result };
|
|
},
|
|
},
|
|
{
|
|
matches: () => getFlagValue("otp") != undefined || hasFlag("otp"),
|
|
run: async ({ cli, logger }) => {
|
|
const runningServer = await checkServerRunning(cli, logger);
|
|
if (runningServer == false) {
|
|
return { handled: true, result: false };
|
|
}
|
|
const result = await runOtpCommand(cli, logger, getFlagValue("otp"));
|
|
return { handled: true, result };
|
|
},
|
|
},
|
|
];
|
|
|
|
export async function handleCommandLine(cli, logger) {
|
|
const command = commands.find((entry) => entry.matches());
|
|
|
|
if (!command) {
|
|
const runningServer = await getRunningServer(cli, logger);
|
|
if (runningServer == null) {
|
|
return { handled: true, result: false };
|
|
}
|
|
return { handled: false, runningServer };
|
|
}
|
|
|
|
const result = await command.run({ cli, logger });
|
|
return { handled: true, result };
|
|
}
|