sesterce-cli
Version:
A powerful command-line interface tool for managing Sesterce Cloud services. Sesterce CLI provides easy access to GPU cloud instances, AI inference services, container registries, and SSH key management directly from your terminal.
274 lines (255 loc) • 12.9 kB
text/typescript
import { GpuCloudInstance } from "@/modules/gpu-cloud/domain/instance/instance";
import { getInstanceDetails } from "@/modules/gpu-cloud/use-cases/get-instance-details";
import { listLaunchedInstances } from "@/modules/gpu-cloud/use-cases/list-launched-instances";
import { search } from "@inquirer/prompts";
import chalk from "chalk";
import { Command } from "commander";
import figlet from "figlet";
import { DateTime } from "luxon";
const getStatusColor = (status: GpuCloudInstance["status"]) => {
switch (status) {
case "active":
return chalk.hex("#50FA7B"); // Green
case "pending":
return chalk.hex("#FFB86C"); // Orange
case "error":
return chalk.hex("#FF5555"); // Red
case "deleted":
return chalk.hex("#6272A4"); // Gray
default:
return chalk.white;
}
};
const printInstance = (instance: GpuCloudInstance) => {
return `${instance.name} (${instance.gpuCount} x ${instance.gpuModel}) | ${instance.provider} | ${instance.region.name} | ${instance.status} | ${instance.hourlyPrice.toFixed(2)}`;
};
export function createGpuCloudInstanceDetailsCommand(
gpuCloudInstanceCommand: Command
) {
gpuCloudInstanceCommand
.command("details")
.description("Get details of a launched instance in Sesterce Cloud")
.option(
"-i, --instance-id <instanceId>",
"The ID of the instance to get details of"
)
.action(async (args) => {
let instanceId = args.instanceId;
if (!instanceId) {
console.log("Loading launched instances...");
const result = await listLaunchedInstances.execute();
if (result.isLeft()) {
console.error(result.value.message);
return;
}
const instances = result.value;
if (instances.length === 0) {
console.log("No instances found");
return;
}
const instance = await search({
message: "Select an instance to get details for",
source: async (input) => {
if (!input) {
return instances.map((instance) => ({
name: printInstance(instance),
value: instance,
}));
}
return instances
.filter(
(instance) =>
instance.gpuModel
.toLowerCase()
.includes(input.toLowerCase()) ||
instance.gpuCount.toString().includes(input) ||
instance.region.name.toLowerCase().includes(input) ||
instance.provider.toLowerCase().includes(input) ||
instance.status.toLowerCase().includes(input) ||
instance.name.toLowerCase().includes(input) ||
instance.hourlyPrice.toFixed(2).includes(input)
)
.map((instance) => ({
name: printInstance(instance),
value: instance,
}));
},
});
instanceId = instance._id;
}
const result = await getInstanceDetails.execute(instanceId);
if (result.isLeft()) {
console.error(result.value.message);
return;
}
const instance = result.value;
// Header with instance name
console.log("\n" + "=".repeat(80));
console.log(
chalk.hex("#21C65D")(
figlet.textSync(instance.name, { font: "Standard" })
)
);
console.log("=".repeat(80) + "\n");
// Basic Information Section
console.log(chalk.hex("#FF6B6B")(chalk.bold("📋 BASIC INFORMATION")));
console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐"));
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("ID:")} ${chalk.white(instance._id)}${" ".repeat(78 - 4 - instance._id.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Name:")} ${chalk.white(instance.name)}${" ".repeat(78 - 6 - instance.name.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Status:")} ${getStatusColor(instance.status)(instance.status)}${" ".repeat(78 - 8 - instance.status.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Provider:")} ${chalk.cyan(instance.provider)}${" ".repeat(78 - 10 - instance.provider.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Region:")} ${chalk.white(instance.region.name)}${" ".repeat(78 - 8 - instance.region.name.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("IP Address:")} ${instance.ip ? chalk.cyan(instance.ip) : chalk.gray("Not assigned")}${" ".repeat(78 - 12 - (instance.ip ? instance.ip.length : 12))}${chalk.hex("#4ECDC4")("│")}`
);
console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n"));
// Hardware Specifications Section
console.log(
chalk.hex("#FF6B6B")(chalk.bold("🚀 HARDWARE SPECIFICATIONS"))
);
console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐"));
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("GPU Model:")} ${chalk.hex("#FFE66D")(instance.gpuModel)}${" ".repeat(78 - 11 - instance.gpuModel.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("GPU Count:")} ${chalk.white(instance.gpuCount)}${" ".repeat(78 - 11 - instance.gpuCount.toString().length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Total VRAM:")} ${chalk.hex("#50FA7B")(`${instance.vramPerGpu * instance.gpuCount} GB`)}${" ".repeat(78 - 12 - `${instance.vramPerGpu * instance.gpuCount} GB`.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("RAM:")} ${chalk.white(`${instance.ram} GB`)}${" ".repeat(78 - 5 - `${instance.ram} GB`.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Storage:")} ${chalk.white(`${instance.storage} GB`)}${" ".repeat(78 - 9 - `${instance.storage} GB`.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("vCPUs:")} ${chalk.white(instance.vcpus)}${" ".repeat(78 - 7 - instance.vcpus.toString().length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Interconnect:")} ${chalk.white(instance.interconnect)}${" ".repeat(78 - 13 - instance.interconnect.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("NVLink:")} ${instance.nvlink ? chalk.hex("#50FA7B")("Yes") : chalk.red("No")}${" ".repeat(78 - 8 - (instance.nvlink ? 3 : 2))}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("OS:")} ${chalk.white(instance.os)}${" ".repeat(78 - 4 - instance.os.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Hourly Price:")} ${chalk.hex("#50FA7B")(`$${instance.hourlyPrice.toFixed(2)}`)}${" ".repeat(78 - 13 - instance.hourlyPrice.toFixed(2).length - 1)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n"));
// SSH Configuration Section
console.log(chalk.hex("#FF6B6B")(chalk.bold("🔑 SSH CONFIGURATION")));
console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐"));
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("SSH Key:")} ${chalk.white(instance.sshKey.name)}${" ".repeat(78 - 10 - instance.sshKey.name.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("SSH User:")} ${chalk.white(instance.sshUser)}${" ".repeat(78 - 10 - instance.sshUser.length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("SSH Port:")} ${instance.sshPort ? chalk.white(instance.sshPort) : chalk.gray("Not assigned")}${" ".repeat(78 - 10 - (instance.sshPort ? instance.sshPort.toString().length : 12))}${chalk.hex("#4ECDC4")("│")}`
);
console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n"));
// Docker Configuration Section
if (instance.dockerImage || instance.dockerCommand) {
console.log(
chalk.hex("#FF6B6B")(chalk.bold("🐳 DOCKER CONFIGURATION"))
);
console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐"));
if (instance.dockerImage) {
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Docker Image:")} ${chalk.white(instance.dockerImage)}${" ".repeat(78 - 14 - instance.dockerImage.length)}${chalk.hex("#4ECDC4")("│")}`
);
}
if (instance.dockerCommand) {
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Docker Command:")} ${chalk.white(instance.dockerCommand)}${" ".repeat(78 - 16 - instance.dockerCommand.length)}${chalk.hex("#4ECDC4")("│")}`
);
}
console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n"));
}
// Port Forwards Section
if (instance.portForwards && instance.portForwards.length > 0) {
console.log(chalk.hex("#FF6B6B")(chalk.bold("🔌 PORT FORWARDS")));
console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐"));
instance.portForwards.forEach((port, index) => {
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold(`Port ${index + 1}:`)} ${chalk.cyan(`${port.internalPort} → ${port.externalPort}`)}${" ".repeat(78 - 9 - `${port.internalPort} → ${port.externalPort}`.length)}${chalk.hex("#4ECDC4")("│")}`
);
});
console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n"));
}
// Volumes Section
if (instance.volumes && instance.volumes.length > 0) {
console.log(chalk.hex("#FF6B6B")(chalk.bold("💾 MOUNTED VOLUMES")));
console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐"));
instance.volumes.forEach((volume, index) => {
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold(`Volume ${index + 1}:`)} ${chalk.white(volume.name)} (${chalk.hex("#50FA7B")(`${volume.capacity} GB`)} - $${volume.hourlyPrice.toFixed(2)}/hour)${" ".repeat(78 - 12 - volume.name.length - `${volume.capacity} GB`.length - volume.hourlyPrice.toFixed(2).length - 8)}${chalk.hex("#4ECDC4")("│")}`
);
});
console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n"));
}
// Timestamps Section
console.log(chalk.hex("#FF6B6B")(chalk.bold("⏰ TIMESTAMPS")));
console.log(chalk.hex("#4ECDC4")("┌─" + "─".repeat(78) + "─┐"));
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Created:")} ${chalk.white(DateTime.fromISO(instance.createdAt).toLocaleString(DateTime.DATETIME_FULL))}${" ".repeat(78 - 9 - DateTime.fromISO(instance.createdAt).toLocaleString(DateTime.DATETIME_FULL).length)}${chalk.hex("#4ECDC4")("│")}`
);
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Updated:")} ${chalk.white(DateTime.fromISO(instance.updatedAt).toLocaleString(DateTime.DATETIME_FULL))}${" ".repeat(78 - 9 - DateTime.fromISO(instance.updatedAt).toLocaleString(DateTime.DATETIME_FULL).length)}${chalk.hex("#4ECDC4")("│")}`
);
if (instance.deletedAt) {
console.log(
chalk.hex("#4ECDC4")("│") +
` ${chalk.bold("Deleted:")} ${chalk.red(DateTime.fromISO(instance.deletedAt).toLocaleString(DateTime.DATETIME_FULL))}${" ".repeat(78 - 9 - DateTime.fromISO(instance.deletedAt).toLocaleString(DateTime.DATETIME_FULL).length)}${chalk.hex("#4ECDC4")("│")}`
);
}
console.log(chalk.hex("#4ECDC4")("└─" + "─".repeat(78) + "─┘\n"));
// Footer
console.log(chalk.hex("#21C65D")("=".repeat(80)));
console.log(
chalk.hex("#21C65D")(
chalk.bold("✨ GPU Cloud instance details displayed successfully!")
)
);
console.log(chalk.hex("#21C65D")("=".repeat(80)) + "\n");
});
}