Files
kuber/command/s3.ts
T
2026-08-30 18:51:19 +07:00

90 lines
2.1 KiB
TypeScript

import { defineCommand } from "citty";
import { ctx } from "../lib/context";
import { toTable } from "../lib/format";
import {
getComposeS3Claims,
getS3Credentials,
type S3Claim,
} from "../lib/storage";
const GARAGE_UI_URL = "http://garage-ui.garage-system.svc.cluster.local";
export function getS3UiUrl(bucket: string): string {
return `${GARAGE_UI_URL}/buckets/${encodeURIComponent(bucket)}/objects`;
}
async function getServiceClaim(service: string): Promise<S3Claim> {
const claim = getComposeS3Claims(await ctx().compose()).find(
(entry) => entry.service === service,
);
if (!claim) {
throw new Error(`Service ${service} does not declare a managed S3 volume.`);
}
return claim;
}
const list = defineCommand({
meta: {
name: "ls",
description: "List managed S3 claims",
},
async run() {
const claims = getComposeS3Claims(await ctx().compose());
if (claims.length === 0) {
console.log("No managed S3 volumes declared");
return;
}
console.log(
toTable(
claims.map((claim) => ({
service: claim.service,
key: claim.key,
bucket: claim.bucket,
})),
),
);
},
});
const creds = defineCommand({
meta: {
name: "creds",
description: "Print S3 environment variables for a service",
},
async run({ args }) {
const service = args._[0];
if (!service) throw new Error("Service name is required");
const credentials = await getS3Credentials(await getServiceClaim(service));
for (const [name, value] of Object.entries(credentials)) {
console.log(`${name}=${value}`);
}
},
});
const ui = defineCommand({
meta: {
name: "ui",
description: "Print the Garage UI URL for a service bucket",
},
async run({ args }) {
const service = args._[0];
if (!service) throw new Error("Service name is required");
console.log(getS3UiUrl((await getServiceClaim(service)).bucket));
},
});
export const s3 = defineCommand({
meta: {
name: "s3",
description: "Inspect managed S3 storage",
},
subCommands: {
creds,
ls: list,
ui,
},
});