Skip to content

Commit

Permalink
feat: add storage providers commands (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
ps-kwang authored Apr 8, 2024
1 parent 0137724 commit 198690e
Show file tree
Hide file tree
Showing 11 changed files with 482 additions and 3 deletions.
6 changes: 3 additions & 3 deletions api/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ export interface paths {
*/
post: operations["startupScripts-unassign"];
};
"/storage": {
"/storage-providers": {
/**
* List storage providers
* @description List storage providers
Expand All @@ -707,7 +707,7 @@ export interface paths {
*/
post: operations["storageProviders-create"];
};
"/storage/{id}": {
"/storage-providers/{id}": {
/**
* Get a storage provider
* @description Get a storage provider
Expand All @@ -724,7 +724,7 @@ export interface paths {
*/
delete: operations["storageProviders-delete"];
};
"/storage/utilization": {
"/storage-providers/utilization": {
/**
* Get storage utilization
* @description Get a breakdown of how storage is being used by your team
Expand Down
9 changes: 9 additions & 0 deletions api/storage-providers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { client } from "./client.ts";

export const storageProviders = {
create: client("/storage-providers").post,
get: client("/storage-providers/{id}").get,
list: client("/storage-providers").get,
update: client("/storage-providers/{id}").put,
delete: client("/storage-providers/{id}").delete,
};
2 changes: 2 additions & 0 deletions commands/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { sharedDrive } from "./shared-drive/mod.ts";
import { signup } from "./signup/mod.ts";
import { snapshot } from "./snapshot/mod.ts";
import { startupScript } from "./startup-script/mod.ts";
import { storageProvider } from "./storage-provider/mod.ts";
import { template } from "./template/mod.ts";
import { up } from "./up/mod.ts";
import { getLatestVersion, upgrade } from "./upgrade/mod.ts";
Expand Down Expand Up @@ -56,6 +57,7 @@ export const commands = [
snapshot,
sharedDrive,
startupScript,
storageProvider,
template,
up,
upgrade,
Expand Down
20 changes: 20 additions & 0 deletions commands/storage-provider/create/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { command } from "../../../zcli.ts";
import { s3 } from "./s3/mod.ts";

/**
* This variable is automatically generated by `zcli add`. Do not remove this
* or change its name unless you're no longer using `zcli add`.
*/
const subCommands: ReturnType<typeof command>[] = [s3];

export const create = command("create", {
short: "Create a storage provider",
long: `
Create a storage provider.
`,
commands: subCommands,
}).run(function* ({ ctx }) {
for (const line of create.help(ctx)) {
yield line;
}
});
93 changes: 93 additions & 0 deletions commands/storage-provider/create/s3/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { storageProviders } from "../../../../api/storage-providers.ts";
import { fields } from "../../../../flags.ts";
import { asserts } from "../../../../lib/asserts.ts";
import { dataTable } from "../../../../lib/data-table.ts";
import { loading } from "../../../../lib/loading.ts";
import { pickJson } from "../../../../lib/pick-json.ts";
import { command, flag, flags } from "../../../../zcli.ts";
import { defaultFields } from "../../mod.ts";

/**
* This variable is automatically generated by `zcli add`. Do not remove this
* or change its name unless you're no longer using `zcli add`.
*/
const subCommands: ReturnType<typeof command>[] = [];

export const s3 = command("s3", {
short: "Create an S3 storage provider",
long: `
Create an S3 storage provider.
`,
commands: subCommands,
flags: flags({
fields,
}).merge(flags({
"name": flag({
aliases: ["n"],
short: "The name of the storage provider",
}).string(),
"is-team-default": flag({
short: "Whether the storage provider is the team's default provider",
}).oboolean(),
"endpoint": flag({
short: "The endpoint of the storage provider",
}).ostring(),
"bucket": flag({
short: "The bucket of the storage provider",
}).string(),
"region": flag({
short: "The region of the storage provider",
}).ostring(),
"access-key": flag({
short: "The access key of the storage provider",
}).string(),
"secret-access-key": flag({
short: "The secret access key of the storage provider",
}).string(),
"signature-version": flag({
short: "The signature version of the storage provider",
}).ostring(),
"retain-data": flag({
short: "Whether to retain data in the storage provider",
}).oboolean(),
})),
// We use command metadata in the `persistentPreRun` function to check if a
// command requires an API key. If it does, we'll check to see if one is
// set. If not, we'll throw an error.
meta: {
requireApiKey: true,
requireInGoodStanding: true,
},
}).run(
async function* ({ flags }) {
const response = await loading(
storageProviders.create({
name: flags.name,
isTeamDefault: flags["is-team-default"],
storageProviderType: "s3",
s3Config: {
endpoint: flags.endpoint,
bucket: flags.bucket,
region: flags.region,
accessKey: flags["access-key"],
secretAccessKey: flags["secret-access-key"],
signatureVersion: flags["signature-version"],
retainData: flags["retain-data"],
},
}),
);

asserts(response.ok, response);
const result = response.data;

if (flags.json) {
yield pickJson(result, flags.fields);
} else {
for await (
const line of dataTable([result], flags.fields ?? defaultFields)
) {
yield line;
}
}
},
);
63 changes: 63 additions & 0 deletions commands/storage-provider/delete/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { storageProviders } from "../../../api/storage-providers.ts";
import { fields } from "../../../flags.ts";
import { asserts } from "../../../lib/asserts.ts";
import { dataTable } from "../../../lib/data-table.ts";
import { loading } from "../../../lib/loading.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { input } from "../../../prompts/input.ts";
import { args, command, flags, z } from "../../../zcli.ts";
import { defaultFields } from "../mod.ts";

/**
* This variable is automatically generated by `zcli add`. Do not remove this
* or change its name unless you're no longer using `zcli add`.
*/
const subCommands: ReturnType<typeof command>[] = [];

export const del = command("delete", {
short: "Delete a storage provider",
long: `
Delete a storage provider from a team.
`,
commands: subCommands,
args: args().tuple([
z.string().describe("The ID of the storage provider to delete"),
]).optional(),
flags: flags({
fields,
}),
// We use command metadata in the `persistentPreRun` function to check if a
// command requires an API key. If it does, we'll check to see if one is
// set. If not, we'll throw an error.
meta: {
requireApiKey: true,
},
}).run(
async function* ({ args, flags }) {
let [id] = args;

if (!id) {
id = await input("ID:", {
filter: (v) => !!v.sequence.match(/[a-zA-Z0-9_-]/),
});
asserts(id, "A storage provider ID is required");
}

const response = await loading(
storageProviders.delete({ id }),
);

asserts(response.ok, response);
const result = response.data;

if (flags.json) {
yield pickJson(result, flags.fields);
} else {
for await (
const line of dataTable([result], flags.fields ?? defaultFields)
) {
yield line;
}
}
},
);
63 changes: 63 additions & 0 deletions commands/storage-provider/get/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { storageProviders } from "../../../api/storage-providers.ts";
import { fields } from "../../../flags.ts";
import { asserts } from "../../../lib/asserts.ts";
import { dataTable } from "../../../lib/data-table.ts";
import { loading } from "../../../lib/loading.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { input } from "../../../prompts/input.ts";
import { args, command, flags, z } from "../../../zcli.ts";
import { defaultFields } from "../mod.ts";

/**
* This variable is automatically generated by `zcli add`. Do not remove this
* or change its name unless you're no longer using `zcli add`.
*/
const subCommands: ReturnType<typeof command>[] = [];

export const get = command("get", {
short: "Get a storage provider",
long: `
Get a storage provider from a team.
`,
commands: subCommands,
args: args().tuple([
z.string().describe("The ID of the storage provider to get"),
]).optional(),
flags: flags({
fields,
}),
// We use command metadata in the `persistentPreRun` function to check if a
// command requires an API key. If it does, we'll check to see if one is
// set. If not, we'll throw an error.
meta: {
requireApiKey: true,
},
}).run(
async function* ({ args, flags }) {
let [id] = args;

if (!id) {
id = await input("ID:", {
filter: (v) => !!v.sequence.match(/[a-zA-Z0-9_-]/),
});
asserts(id, "A storage provider ID is required");
}

const response = await loading(
storageProviders.get({ id }),
);

asserts(response.ok, response);
const result = response.data;

if (flags.json) {
yield pickJson(result, flags.fields);
} else {
for await (
const line of dataTable([result], flags.fields ?? defaultFields)
) {
yield line;
}
}
},
);
63 changes: 63 additions & 0 deletions commands/storage-provider/list/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { storageProviders } from "../../../api/storage-providers.ts";
import { config } from "../../../config.ts";
import * as psFlags from "../../../flags.ts";
import { asserts } from "../../../lib/asserts.ts";
import { dataTable } from "../../../lib/data-table.ts";
import { loading } from "../../../lib/loading.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { command } from "../../../zcli.ts";
import { defaultFields } from "../mod.ts";

/**
* This variable is automatically generated by `zcli add`. Do not remove this
* or change its name unless you're no longer using `zcli add`.
*/
const subCommands: ReturnType<typeof command>[] = [];

export const list = command("list", {
short: "List storage providers.",
long: ({ root }) => `
List storage providers in your team or project.
Pick a subset of fields to display:
\`\`\`
${root.name} storage provider list -F name -F dtModified
\`\`\`
`,
commands: subCommands,
flags: psFlags.paginator,
// We use command metadata in the `persistentPreRun` function to check if a
// command requires an API key. If it does, we'll check to see if one is
// set. If not, we'll throw an error.
meta: {
requireApiKey: true,
},
}).run(
async function* ({ flags }) {
const team = await config.get("team");
asserts(team, "You must be in a team to list storage providers.");
const result = await loading(
storageProviders.list({
limit: flags.limit,
after: flags.after,
order: flags.asc ? "asc" : undefined,
}),
{ enabled: !flags.json },
);

asserts(result.ok, result);

if (!flags.json) {
for await (
const line of dataTable(
result.data.items,
flags.fields ?? defaultFields,
)
) {
yield line;
}
} else {
yield pickJson(result.data, flags.fields);
}
},
);
Loading

0 comments on commit 198690e

Please sign in to comment.