kiwivm-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -36
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +370 -50
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/admin.test.ts +135 -22
- package/src/commands/admin.ts +57 -19
- package/src/commands/backup.test.ts +26 -23
- package/src/commands/backup.ts +13 -15
- package/src/commands/help.test.ts +27 -7
- package/src/commands/help.ts +61 -26
- package/src/commands/info.test.ts +47 -43
- package/src/commands/info.ts +11 -13
- package/src/commands/iso.test.ts +58 -0
- package/src/commands/iso.ts +21 -0
- package/src/commands/migrate.test.ts +105 -0
- package/src/commands/migrate.ts +38 -0
- package/src/commands/network.test.ts +107 -30
- package/src/commands/network.ts +56 -18
- package/src/commands/power.test.ts +58 -40
- package/src/commands/power.ts +27 -16
- package/src/commands/shell.test.ts +66 -0
- package/src/commands/shell.ts +25 -0
- package/src/commands/snapshot.test.ts +141 -71
- package/src/commands/snapshot.ts +85 -33
- package/src/commands/stats.test.ts +81 -0
- package/src/commands/stats.ts +25 -0
- package/src/commands/system.test.ts +109 -40
- package/src/commands/system.ts +55 -23
- package/src/index.test.ts +435 -148
- package/src/index.ts +129 -57
- package/src/types.ts +57 -1
- package/dist/admin-fOud1ZmX.mjs +0 -15
- package/dist/admin-fOud1ZmX.mjs.map +0 -1
- package/dist/backup-D1UJ4aap.mjs +0 -12
- package/dist/backup-D1UJ4aap.mjs.map +0 -1
- package/dist/help-Dk-WApoi.mjs +0 -40
- package/dist/help-Dk-WApoi.mjs.map +0 -1
- package/dist/info-DKExtFYH.mjs +0 -13
- package/dist/info-DKExtFYH.mjs.map +0 -1
- package/dist/monitoring-BSuv8fj9.mjs +0 -13
- package/dist/monitoring-BSuv8fj9.mjs.map +0 -1
- package/dist/network-1ycEIJqT.mjs +0 -15
- package/dist/network-1ycEIJqT.mjs.map +0 -1
- package/dist/power-CDg0Mx1A.mjs +0 -14
- package/dist/power-CDg0Mx1A.mjs.map +0 -1
- package/dist/snapshot-LO_ufoj5.mjs +0 -23
- package/dist/snapshot-LO_ufoj5.mjs.map +0 -1
- package/dist/system-Bl-dsqX9.mjs +0 -21
- package/dist/system-Bl-dsqX9.mjs.map +0 -1
- package/src/commands/monitoring.test.ts +0 -82
- package/src/commands/monitoring.ts +0 -20
package/src/index.ts
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { KiwiVMClient } from "./client.ts";
|
|
4
|
+
import * as admin from "./commands/admin.ts";
|
|
5
|
+
import * as backup from "./commands/backup.ts";
|
|
6
|
+
import * as help from "./commands/help.ts";
|
|
7
|
+
import * as info from "./commands/info.ts";
|
|
8
|
+
import * as iso from "./commands/iso.ts";
|
|
9
|
+
import * as migrate from "./commands/migrate.ts";
|
|
10
|
+
import * as network from "./commands/network.ts";
|
|
11
|
+
import * as power from "./commands/power.ts";
|
|
12
|
+
import * as shell from "./commands/shell.ts";
|
|
13
|
+
import * as snapshot from "./commands/snapshot.ts";
|
|
14
|
+
import * as stats from "./commands/stats.ts";
|
|
15
|
+
import * as system from "./commands/system.ts";
|
|
4
16
|
import { KiwiVMError } from "./types.ts";
|
|
5
17
|
|
|
18
|
+
type Handler = (
|
|
19
|
+
args: string[],
|
|
20
|
+
flags: Record<string, string>,
|
|
21
|
+
client: KiwiVMClient,
|
|
22
|
+
) => Promise<unknown>;
|
|
23
|
+
|
|
24
|
+
interface SubcommandRoutes {
|
|
25
|
+
default?: Handler;
|
|
26
|
+
[subcommand: string]: Handler | undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
6
29
|
function parseFlags(args: string[]): Record<string, string> {
|
|
7
30
|
const flags: Record<string, string> = {};
|
|
8
31
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -20,9 +43,8 @@ function parseFlags(args: string[]): Record<string, string> {
|
|
|
20
43
|
flags[toCamelCase(key)] = next;
|
|
21
44
|
i++;
|
|
22
45
|
} else {
|
|
23
|
-
// --flag with no value (treat as boolean/empty string)
|
|
24
46
|
const key = arg.slice(2);
|
|
25
|
-
flags[toCamelCase(key)] = "";
|
|
47
|
+
flags[toCamelCase(key)] = "1";
|
|
26
48
|
}
|
|
27
49
|
}
|
|
28
50
|
}
|
|
@@ -30,7 +52,6 @@ function parseFlags(args: string[]): Record<string, string> {
|
|
|
30
52
|
}
|
|
31
53
|
|
|
32
54
|
function toCamelCase(key: string): string {
|
|
33
|
-
// Known mappings: kebab-case flags that need camelCase API param names
|
|
34
55
|
const known: Record<string, string> = {
|
|
35
56
|
"backup-token": "backupToken",
|
|
36
57
|
"new-hostname": "newHostname",
|
|
@@ -43,7 +64,6 @@ function toCamelCase(key: string): string {
|
|
|
43
64
|
};
|
|
44
65
|
if (known[key]) return known[key];
|
|
45
66
|
|
|
46
|
-
// Default: convert --some-flag to someFlag
|
|
47
67
|
return key.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());
|
|
48
68
|
}
|
|
49
69
|
|
|
@@ -70,18 +90,13 @@ async function main() {
|
|
|
70
90
|
const args = process.argv.slice(2);
|
|
71
91
|
const { positional, flags } = getCommandFromArgs(args);
|
|
72
92
|
|
|
73
|
-
const
|
|
74
|
-
const action = positional[1] ?? "";
|
|
93
|
+
const command = positional[0] ?? "";
|
|
75
94
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const { run } = await import("./commands/help.ts");
|
|
79
|
-
const text = await run();
|
|
80
|
-
console.log(text as string);
|
|
95
|
+
if (command === "" || command === "help") {
|
|
96
|
+
console.log(await help.run());
|
|
81
97
|
return;
|
|
82
98
|
}
|
|
83
99
|
|
|
84
|
-
// Resolve auth: flags first, then env vars
|
|
85
100
|
const flagVeid = flags["veid"];
|
|
86
101
|
const flagApiKey = flags["apiKey"];
|
|
87
102
|
const resolvedVeid = flagVeid || process.env["KIWIVM_VEID"];
|
|
@@ -94,7 +109,6 @@ async function main() {
|
|
|
94
109
|
process.exit(1);
|
|
95
110
|
}
|
|
96
111
|
|
|
97
|
-
// Strip auth flags before passing to handlers
|
|
98
112
|
const handlerFlags = { ...flags };
|
|
99
113
|
delete handlerFlags["veid"];
|
|
100
114
|
delete handlerFlags["apiKey"];
|
|
@@ -107,52 +121,111 @@ async function main() {
|
|
|
107
121
|
try {
|
|
108
122
|
let result: unknown;
|
|
109
123
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
124
|
+
const ROUTES: Record<string, Handler | SubcommandRoutes> = {
|
|
125
|
+
start: power.start,
|
|
126
|
+
stop: power.stop,
|
|
127
|
+
restart: power.restart,
|
|
128
|
+
kill: power.kill,
|
|
129
|
+
info: info.info,
|
|
130
|
+
status: info.status,
|
|
131
|
+
hostname: system.hostname,
|
|
132
|
+
password: system.password,
|
|
133
|
+
suspensions: admin.suspensions,
|
|
134
|
+
unsuspend: admin.unsuspend,
|
|
135
|
+
clone: migrate.clone,
|
|
136
|
+
|
|
137
|
+
snapshot: {
|
|
138
|
+
list: snapshot.list,
|
|
139
|
+
create: snapshot.create,
|
|
140
|
+
delete: snapshot.deleteSnapshot,
|
|
141
|
+
restore: snapshot.restore,
|
|
142
|
+
sticky: snapshot.sticky,
|
|
143
|
+
export: snapshot.exportSnapshot,
|
|
144
|
+
import: snapshot.importSnapshot,
|
|
145
|
+
},
|
|
146
|
+
backup: {
|
|
147
|
+
list: backup.list,
|
|
148
|
+
copy: backup.copy,
|
|
149
|
+
},
|
|
150
|
+
os: {
|
|
151
|
+
list: system.osList,
|
|
152
|
+
reinstall: system.osReinstall,
|
|
153
|
+
},
|
|
154
|
+
"ssh-key": {
|
|
155
|
+
default: system.sshKeyShow,
|
|
156
|
+
set: system.sshKeySet,
|
|
157
|
+
},
|
|
158
|
+
rdns: {
|
|
159
|
+
set: network.rdnsSet,
|
|
160
|
+
},
|
|
161
|
+
ipv6: {
|
|
162
|
+
add: network.ipv6Add,
|
|
163
|
+
delete: network.ipv6Delete,
|
|
164
|
+
},
|
|
165
|
+
"private-ip": {
|
|
166
|
+
list: network.privateIpList,
|
|
167
|
+
assign: network.privateIpAssign,
|
|
168
|
+
delete: network.privateIpDelete,
|
|
169
|
+
},
|
|
170
|
+
iso: {
|
|
171
|
+
mount: iso.mount,
|
|
172
|
+
unmount: iso.unmount,
|
|
173
|
+
},
|
|
174
|
+
shell: {
|
|
175
|
+
exec: shell.exec,
|
|
176
|
+
script: shell.script,
|
|
177
|
+
},
|
|
178
|
+
migrate: {
|
|
179
|
+
locations: migrate.locations,
|
|
180
|
+
start: migrate.migrateStart,
|
|
181
|
+
},
|
|
182
|
+
stats: {
|
|
183
|
+
usage: stats.usage,
|
|
184
|
+
audit: stats.audit,
|
|
185
|
+
"rate-limit": stats.rateLimit,
|
|
186
|
+
},
|
|
187
|
+
violations: {
|
|
188
|
+
default: admin.violationsList,
|
|
189
|
+
resolve: admin.violationsResolve,
|
|
190
|
+
},
|
|
191
|
+
notifications: {
|
|
192
|
+
default: admin.notificationsGet,
|
|
193
|
+
set: admin.notificationsSet,
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const route = ROUTES[command];
|
|
198
|
+
|
|
199
|
+
if (!route) {
|
|
200
|
+
console.error(`Unknown command: ${command}`);
|
|
201
|
+
console.error("Run 'kiwivm-cli help' for usage.");
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (typeof route === "function") {
|
|
206
|
+
result = await route(positional.slice(1), handlerFlags, client);
|
|
207
|
+
} else {
|
|
208
|
+
const subcommand = positional[1];
|
|
209
|
+
let handler: Handler | undefined;
|
|
210
|
+
|
|
211
|
+
if (subcommand && subcommand in route) {
|
|
212
|
+
handler = route[subcommand];
|
|
213
|
+
} else if (!subcommand && route.default) {
|
|
214
|
+
handler = route.default;
|
|
150
215
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
216
|
+
|
|
217
|
+
if (!handler) {
|
|
218
|
+
const valid = Object.keys(route)
|
|
219
|
+
.filter((k) => k !== "default")
|
|
220
|
+
.join(", ");
|
|
221
|
+
const sc = subcommand || "(none)";
|
|
222
|
+
console.error(
|
|
223
|
+
`Unknown subcommand for ${command}: ${sc}. Valid: ${valid}`,
|
|
224
|
+
);
|
|
154
225
|
process.exit(1);
|
|
155
226
|
}
|
|
227
|
+
|
|
228
|
+
result = await handler(positional.slice(2), handlerFlags, client);
|
|
156
229
|
}
|
|
157
230
|
|
|
158
231
|
console.log(JSON.stringify(result));
|
|
@@ -166,7 +239,6 @@ async function main() {
|
|
|
166
239
|
|
|
167
240
|
export { main };
|
|
168
241
|
|
|
169
|
-
// Only auto-run when executed directly (not when imported by tests)
|
|
170
242
|
if (!process.env["VITEST"]) {
|
|
171
243
|
main();
|
|
172
244
|
}
|
package/src/types.ts
CHANGED
|
@@ -16,10 +16,12 @@ export class KiwiVMError extends Error {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export interface ServiceInfo extends KiwiVMResponse {
|
|
19
|
+
vm_type?: "ovz" | "kvm";
|
|
19
20
|
hostname?: string;
|
|
20
21
|
node_alias?: string;
|
|
21
22
|
node_location?: string;
|
|
22
23
|
location_ipv6_ready?: number;
|
|
24
|
+
monthly_data_multiplier?: number;
|
|
23
25
|
plan?: string;
|
|
24
26
|
plan_monthly_data?: number;
|
|
25
27
|
plan_disk?: number;
|
|
@@ -55,7 +57,6 @@ export interface ServiceInfo extends KiwiVMResponse {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export interface LiveServiceInfo extends ServiceInfo {
|
|
58
|
-
vm_type?: "ovz" | "kvm";
|
|
59
60
|
vz_status?: Record<string, unknown>;
|
|
60
61
|
vz_quota?: Record<string, unknown>;
|
|
61
62
|
ve_status?: "Starting" | "Running" | "Stopped";
|
|
@@ -92,3 +93,58 @@ export interface Backup {
|
|
|
92
93
|
md5: string;
|
|
93
94
|
timestamp: number;
|
|
94
95
|
}
|
|
96
|
+
|
|
97
|
+
export interface RateLimitStatus extends KiwiVMResponse {
|
|
98
|
+
remaining_points_15min: number;
|
|
99
|
+
remaining_points_24h: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface SuspensionRecord {
|
|
103
|
+
record_id: number;
|
|
104
|
+
flag: string;
|
|
105
|
+
is_soft: number;
|
|
106
|
+
evidence_record_id: number;
|
|
107
|
+
abuse_points: number;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface SuspensionDetailsResponse extends KiwiVMResponse {
|
|
111
|
+
suspension_count: number;
|
|
112
|
+
total_abuse_points: number;
|
|
113
|
+
max_abuse_points: number;
|
|
114
|
+
suspensions: SuspensionRecord[];
|
|
115
|
+
evidence: Record<string, string>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface PolicyViolation {
|
|
119
|
+
record_id: number;
|
|
120
|
+
timestamp: number;
|
|
121
|
+
suspend_at: number;
|
|
122
|
+
flag: string;
|
|
123
|
+
is_soft: number;
|
|
124
|
+
abuse_points: number;
|
|
125
|
+
evidence_data: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface PolicyViolationsResponse extends KiwiVMResponse {
|
|
129
|
+
total_abuse_points: number;
|
|
130
|
+
max_abuse_points: number;
|
|
131
|
+
policy_violations: PolicyViolation[];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface NotificationPreference {
|
|
135
|
+
id: number;
|
|
136
|
+
name: string;
|
|
137
|
+
description: string;
|
|
138
|
+
value: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface NotificationPreferencesResponse extends KiwiVMResponse {
|
|
142
|
+
email_preferences: NotificationPreference[];
|
|
143
|
+
notificationEmail: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface NotificationSetResponse extends KiwiVMResponse {
|
|
147
|
+
submitted_email_preferences: Record<string, number>;
|
|
148
|
+
updated_email_preferences: Record<string, number>;
|
|
149
|
+
friendly_descriptions: Record<string, string>;
|
|
150
|
+
}
|
package/dist/admin-fOud1ZmX.mjs
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
//#region src/commands/admin.ts
|
|
2
|
-
async function run(action, flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "suspensions": return client.call("getSuspensionDetails");
|
|
5
|
-
case "unsuspend": return client.call("unsuspend", { recordId: flags["recordId"] });
|
|
6
|
-
case "resolve":
|
|
7
|
-
if (flags["recordId"] !== void 0) return client.call("resolvePolicyViolation", { recordId: flags["recordId"] });
|
|
8
|
-
return client.call("getPolicyViolations");
|
|
9
|
-
default: throw new Error(`Unknown admin action: ${action}. Valid: suspensions, unsuspend, resolve`);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
//#endregion
|
|
13
|
-
export { run };
|
|
14
|
-
|
|
15
|
-
//# sourceMappingURL=admin-fOud1ZmX.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"admin-fOud1ZmX.mjs","names":[],"sources":["../src/commands/admin.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"suspensions\":\n return client.call(\"getSuspensionDetails\");\n case \"unsuspend\":\n return client.call(\"unsuspend\", { recordId: flags[\"recordId\"] });\n case \"resolve\":\n if (flags[\"recordId\"] !== undefined) {\n return client.call(\"resolvePolicyViolation\", {\n recordId: flags[\"recordId\"],\n });\n }\n return client.call(\"getPolicyViolations\");\n default:\n throw new Error(\n `Unknown admin action: ${action}. Valid: suspensions, unsuspend, resolve`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,cACH,QAAO,OAAO,KAAK,uBAAuB;EAC5C,KAAK,YACH,QAAO,OAAO,KAAK,aAAa,EAAE,UAAU,MAAM,aAAa,CAAC;EAClE,KAAK;AACH,OAAI,MAAM,gBAAgB,KAAA,EACxB,QAAO,OAAO,KAAK,0BAA0B,EAC3C,UAAU,MAAM,aACjB,CAAC;AAEJ,UAAO,OAAO,KAAK,sBAAsB;EAC3C,QACE,OAAM,IAAI,MACR,yBAAyB,OAAO,0CACjC"}
|
package/dist/backup-D1UJ4aap.mjs
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
//#region src/commands/backup.ts
|
|
2
|
-
async function run(action, flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "list": return client.call("backup/list");
|
|
5
|
-
case "copy": return client.call("backup/copyToSnapshot", { backupToken: flags["backupToken"] });
|
|
6
|
-
default: throw new Error(`Unknown backup action: ${action}. Valid: list, copy`);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
//#endregion
|
|
10
|
-
export { run };
|
|
11
|
-
|
|
12
|
-
//# sourceMappingURL=backup-D1UJ4aap.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"backup-D1UJ4aap.mjs","names":[],"sources":["../src/commands/backup.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\nimport type { Backup, KiwiVMResponse } from \"../types.ts\";\n\ninterface BackupListResponse extends KiwiVMResponse {\n backups: Backup[];\n}\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"list\":\n return client.call<BackupListResponse>(\"backup/list\");\n case \"copy\":\n return client.call(\"backup/copyToSnapshot\", {\n backupToken: flags[\"backupToken\"],\n });\n default:\n throw new Error(`Unknown backup action: ${action}. Valid: list, copy`);\n }\n}\n"],"mappings":";AAOA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,OACH,QAAO,OAAO,KAAyB,cAAc;EACvD,KAAK,OACH,QAAO,OAAO,KAAK,yBAAyB,EAC1C,aAAa,MAAM,gBACpB,CAAC;EACJ,QACE,OAAM,IAAI,MAAM,0BAA0B,OAAO,qBAAqB"}
|
package/dist/help-Dk-WApoi.mjs
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
//#region src/commands/help.ts
|
|
2
|
-
const HELP = `Usage: kiwivm-cli <category> <action> [--flags...]
|
|
3
|
-
|
|
4
|
-
Auth: --veid <VEID> --api-key <KEY> (or KIWIVM_VEID / KIWIVM_API_KEY env vars)
|
|
5
|
-
|
|
6
|
-
Categories:
|
|
7
|
-
|
|
8
|
-
power start | stop | restart | kill
|
|
9
|
-
info (no action) | live
|
|
10
|
-
snapshot create | list | delete | restore | sticky | export | import
|
|
11
|
-
backup list | copy
|
|
12
|
-
system hostname | rdns | password | sshkey | os | reinstall
|
|
13
|
-
network ipv6-add | ipv6-delete | private-list | private-assign | private-delete
|
|
14
|
-
monitoring usage | audit | rate-limit
|
|
15
|
-
admin suspensions | unsuspend | resolve | resolve-violation
|
|
16
|
-
|
|
17
|
-
Flags:
|
|
18
|
-
|
|
19
|
-
--description Snapshot description (snapshot create)
|
|
20
|
-
--snapshot Snapshot file name (snapshot delete/restore/sticky/export)
|
|
21
|
-
--sticky 0 or 1 (snapshot sticky)
|
|
22
|
-
--source-veid Source VEID (snapshot import)
|
|
23
|
-
--source-token Source token (snapshot import)
|
|
24
|
-
--backup-token Backup token (backup copy)
|
|
25
|
-
--new-hostname New hostname (system hostname)
|
|
26
|
-
--ip IP address (system rdns, network ipv6-delete/private-assign/private-delete)
|
|
27
|
-
--ptr PTR/rDNS record (system rdns)
|
|
28
|
-
--ssh-keys SSH keys (system sshkey update)
|
|
29
|
-
--os OS template name (system reinstall)
|
|
30
|
-
--record-id Record ID (admin unsuspend/resolve-violation)
|
|
31
|
-
|
|
32
|
-
Output: JSON to stdout. Errors to stderr with exit code 1.
|
|
33
|
-
`;
|
|
34
|
-
async function run() {
|
|
35
|
-
return HELP;
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
|
-
export { run };
|
|
39
|
-
|
|
40
|
-
//# sourceMappingURL=help-Dk-WApoi.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"help-Dk-WApoi.mjs","names":[],"sources":["../src/commands/help.ts"],"sourcesContent":["const HELP = `Usage: kiwivm-cli <category> <action> [--flags...]\n\nAuth: --veid <VEID> --api-key <KEY> (or KIWIVM_VEID / KIWIVM_API_KEY env vars)\n\nCategories:\n\n power start | stop | restart | kill\n info (no action) | live\n snapshot create | list | delete | restore | sticky | export | import\n backup list | copy\n system hostname | rdns | password | sshkey | os | reinstall\n network ipv6-add | ipv6-delete | private-list | private-assign | private-delete\n monitoring usage | audit | rate-limit\n admin suspensions | unsuspend | resolve | resolve-violation\n\nFlags:\n\n --description Snapshot description (snapshot create)\n --snapshot Snapshot file name (snapshot delete/restore/sticky/export)\n --sticky 0 or 1 (snapshot sticky)\n --source-veid Source VEID (snapshot import)\n --source-token Source token (snapshot import)\n --backup-token Backup token (backup copy)\n --new-hostname New hostname (system hostname)\n --ip IP address (system rdns, network ipv6-delete/private-assign/private-delete)\n --ptr PTR/rDNS record (system rdns)\n --ssh-keys SSH keys (system sshkey update)\n --os OS template name (system reinstall)\n --record-id Record ID (admin unsuspend/resolve-violation)\n\nOutput: JSON to stdout. Errors to stderr with exit code 1.\n`;\n\nexport async function run(): Promise<string> {\n return HELP;\n}\n"],"mappings":";AAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCb,eAAsB,MAAuB;AAC3C,QAAO"}
|
package/dist/info-DKExtFYH.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
//#region src/commands/info.ts
|
|
2
|
-
async function run(action, _flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "live": return client.call("getLiveServiceInfo");
|
|
5
|
-
case "":
|
|
6
|
-
case "info": return client.call("getServiceInfo");
|
|
7
|
-
default: throw new Error(`Unknown info action: ${action}. Valid: (no action), live`);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { run };
|
|
12
|
-
|
|
13
|
-
//# sourceMappingURL=info-DKExtFYH.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"info-DKExtFYH.mjs","names":[],"sources":["../src/commands/info.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\nimport type { LiveServiceInfo, ServiceInfo } from \"../types.ts\";\n\nexport async function run(\n action: string,\n _flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"live\":\n return client.call<LiveServiceInfo>(\"getLiveServiceInfo\");\n case \"\":\n case \"info\":\n return client.call<ServiceInfo>(\"getServiceInfo\");\n default:\n throw new Error(\n `Unknown info action: ${action}. Valid: (no action), live`,\n );\n }\n}\n"],"mappings":";AAGA,eAAsB,IACpB,QACA,QACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,OACH,QAAO,OAAO,KAAsB,qBAAqB;EAC3D,KAAK;EACL,KAAK,OACH,QAAO,OAAO,KAAkB,iBAAiB;EACnD,QACE,OAAM,IAAI,MACR,wBAAwB,OAAO,4BAChC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
//#region src/commands/monitoring.ts
|
|
2
|
-
async function run(action, _flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "usage": return client.call("getRawUsageStats");
|
|
5
|
-
case "audit": return client.call("getAuditLog");
|
|
6
|
-
case "rate-limit": return client.call("getRateLimitStatus");
|
|
7
|
-
default: throw new Error(`Unknown monitoring action: ${action}. Valid: usage, audit, rate-limit`);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { run };
|
|
12
|
-
|
|
13
|
-
//# sourceMappingURL=monitoring-BSuv8fj9.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"monitoring-BSuv8fj9.mjs","names":[],"sources":["../src/commands/monitoring.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n _flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"usage\":\n return client.call(\"getRawUsageStats\");\n case \"audit\":\n return client.call(\"getAuditLog\");\n case \"rate-limit\":\n return client.call(\"getRateLimitStatus\");\n default:\n throw new Error(\n `Unknown monitoring action: ${action}. Valid: usage, audit, rate-limit`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,QACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,QACH,QAAO,OAAO,KAAK,mBAAmB;EACxC,KAAK,QACH,QAAO,OAAO,KAAK,cAAc;EACnC,KAAK,aACH,QAAO,OAAO,KAAK,qBAAqB;EAC1C,QACE,OAAM,IAAI,MACR,8BAA8B,OAAO,mCACtC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
//#region src/commands/network.ts
|
|
2
|
-
async function run(action, flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "ipv6-add": return client.call("ipv6/add");
|
|
5
|
-
case "ipv6-delete": return client.call("ipv6/delete", { ip: flags["ip"] });
|
|
6
|
-
case "private-list": return client.call("privateIp/getAvailableIps");
|
|
7
|
-
case "private-assign": return client.call("privateIp/assign", { ip: flags["ip"] });
|
|
8
|
-
case "private-delete": return client.call("privateIp/delete", { ip: flags["ip"] });
|
|
9
|
-
default: throw new Error(`Unknown network action: ${action}. Valid: ipv6-add, ipv6-delete, private-list, private-assign, private-delete`);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
//#endregion
|
|
13
|
-
export { run };
|
|
14
|
-
|
|
15
|
-
//# sourceMappingURL=network-1ycEIJqT.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"network-1ycEIJqT.mjs","names":[],"sources":["../src/commands/network.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"ipv6-add\":\n return client.call(\"ipv6/add\");\n case \"ipv6-delete\":\n return client.call(\"ipv6/delete\", { ip: flags[\"ip\"] });\n case \"private-list\":\n return client.call(\"privateIp/getAvailableIps\");\n case \"private-assign\":\n return client.call(\"privateIp/assign\", { ip: flags[\"ip\"] });\n case \"private-delete\":\n return client.call(\"privateIp/delete\", { ip: flags[\"ip\"] });\n default:\n throw new Error(\n `Unknown network action: ${action}. Valid: ipv6-add, ipv6-delete, private-list, private-assign, private-delete`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,WACH,QAAO,OAAO,KAAK,WAAW;EAChC,KAAK,cACH,QAAO,OAAO,KAAK,eAAe,EAAE,IAAI,MAAM,OAAO,CAAC;EACxD,KAAK,eACH,QAAO,OAAO,KAAK,4BAA4B;EACjD,KAAK,iBACH,QAAO,OAAO,KAAK,oBAAoB,EAAE,IAAI,MAAM,OAAO,CAAC;EAC7D,KAAK,iBACH,QAAO,OAAO,KAAK,oBAAoB,EAAE,IAAI,MAAM,OAAO,CAAC;EAC7D,QACE,OAAM,IAAI,MACR,2BAA2B,OAAO,8EACnC"}
|
package/dist/power-CDg0Mx1A.mjs
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
//#region src/commands/power.ts
|
|
2
|
-
async function run(action, _flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "start": return client.call("start");
|
|
5
|
-
case "stop": return client.call("stop");
|
|
6
|
-
case "restart": return client.call("restart");
|
|
7
|
-
case "kill": return client.call("kill");
|
|
8
|
-
default: throw new Error(`Unknown power action: ${action}. Valid: start, stop, restart, kill`);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
//#endregion
|
|
12
|
-
export { run };
|
|
13
|
-
|
|
14
|
-
//# sourceMappingURL=power-CDg0Mx1A.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"power-CDg0Mx1A.mjs","names":[],"sources":["../src/commands/power.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n _flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"start\":\n return client.call(\"start\");\n case \"stop\":\n return client.call(\"stop\");\n case \"restart\":\n return client.call(\"restart\");\n case \"kill\":\n return client.call(\"kill\");\n default:\n throw new Error(\n `Unknown power action: ${action}. Valid: start, stop, restart, kill`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,QACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,QACH,QAAO,OAAO,KAAK,QAAQ;EAC7B,KAAK,OACH,QAAO,OAAO,KAAK,OAAO;EAC5B,KAAK,UACH,QAAO,OAAO,KAAK,UAAU;EAC/B,KAAK,OACH,QAAO,OAAO,KAAK,OAAO;EAC5B,QACE,OAAM,IAAI,MACR,yBAAyB,OAAO,qCACjC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
//#region src/commands/snapshot.ts
|
|
2
|
-
async function run(action, flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "create": return client.call("snapshot/create", { description: flags["description"] });
|
|
5
|
-
case "list": return client.call("snapshot/list");
|
|
6
|
-
case "delete": return client.call("snapshot/delete", { snapshot: flags["snapshot"] });
|
|
7
|
-
case "restore": return client.call("snapshot/restore", { snapshot: flags["snapshot"] });
|
|
8
|
-
case "sticky": return client.call("snapshot/toggleSticky", {
|
|
9
|
-
snapshot: flags["snapshot"],
|
|
10
|
-
sticky: flags["sticky"] !== void 0 ? Number(flags["sticky"]) : void 0
|
|
11
|
-
});
|
|
12
|
-
case "export": return client.call("snapshot/export", { snapshot: flags["snapshot"] });
|
|
13
|
-
case "import": return client.call("snapshot/import", {
|
|
14
|
-
sourceVeid: flags["sourceVeid"],
|
|
15
|
-
sourceToken: flags["sourceToken"]
|
|
16
|
-
});
|
|
17
|
-
default: throw new Error(`Unknown snapshot action: ${action}. Valid: create, list, delete, restore, sticky, export, import`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
export { run };
|
|
22
|
-
|
|
23
|
-
//# sourceMappingURL=snapshot-LO_ufoj5.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot-LO_ufoj5.mjs","names":[],"sources":["../src/commands/snapshot.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\nimport type { KiwiVMResponse, Snapshot } from \"../types.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"create\":\n return client.call(\"snapshot/create\", {\n description: flags[\"description\"],\n });\n case \"list\":\n return client.call<KiwiVMResponse & { snapshots: Snapshot[] }>(\n \"snapshot/list\",\n );\n case \"delete\":\n return client.call(\"snapshot/delete\", { snapshot: flags[\"snapshot\"] });\n case \"restore\":\n return client.call(\"snapshot/restore\", { snapshot: flags[\"snapshot\"] });\n case \"sticky\":\n return client.call(\"snapshot/toggleSticky\", {\n snapshot: flags[\"snapshot\"],\n sticky:\n flags[\"sticky\"] !== undefined ? Number(flags[\"sticky\"]) : undefined,\n });\n case \"export\":\n return client.call(\"snapshot/export\", { snapshot: flags[\"snapshot\"] });\n case \"import\":\n return client.call(\"snapshot/import\", {\n sourceVeid: flags[\"sourceVeid\"],\n sourceToken: flags[\"sourceToken\"],\n });\n default:\n throw new Error(\n `Unknown snapshot action: ${action}. Valid: create, list, delete, restore, sticky, export, import`,\n );\n }\n}\n"],"mappings":";AAGA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB,EACpC,aAAa,MAAM,gBACpB,CAAC;EACJ,KAAK,OACH,QAAO,OAAO,KACZ,gBACD;EACH,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB,EAAE,UAAU,MAAM,aAAa,CAAC;EACxE,KAAK,UACH,QAAO,OAAO,KAAK,oBAAoB,EAAE,UAAU,MAAM,aAAa,CAAC;EACzE,KAAK,SACH,QAAO,OAAO,KAAK,yBAAyB;GAC1C,UAAU,MAAM;GAChB,QACE,MAAM,cAAc,KAAA,IAAY,OAAO,MAAM,UAAU,GAAG,KAAA;GAC7D,CAAC;EACJ,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB,EAAE,UAAU,MAAM,aAAa,CAAC;EACxE,KAAK,SACH,QAAO,OAAO,KAAK,mBAAmB;GACpC,YAAY,MAAM;GAClB,aAAa,MAAM;GACpB,CAAC;EACJ,QACE,OAAM,IAAI,MACR,4BAA4B,OAAO,gEACpC"}
|
package/dist/system-Bl-dsqX9.mjs
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
//#region src/commands/system.ts
|
|
2
|
-
async function run(action, flags, client) {
|
|
3
|
-
switch (action) {
|
|
4
|
-
case "hostname": return client.call("setHostname", { newHostname: flags["newHostname"] });
|
|
5
|
-
case "rdns": return client.call("setPTR", {
|
|
6
|
-
ip: flags["ip"],
|
|
7
|
-
ptr: flags["ptr"]
|
|
8
|
-
});
|
|
9
|
-
case "password": return client.call("resetRootPassword");
|
|
10
|
-
case "sshkey":
|
|
11
|
-
if (flags["sshKeys"] !== void 0) return client.call("updateSshKeys", { sshKeys: flags["sshKeys"] });
|
|
12
|
-
return client.call("getSshKeys");
|
|
13
|
-
case "os": return client.call("getAvailableOS");
|
|
14
|
-
case "reinstall": return client.call("reinstallOS", { os: flags["os"] });
|
|
15
|
-
default: throw new Error(`Unknown system action: ${action}. Valid: hostname, rdns, password, sshkey, os, reinstall`);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
//#endregion
|
|
19
|
-
export { run };
|
|
20
|
-
|
|
21
|
-
//# sourceMappingURL=system-Bl-dsqX9.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system-Bl-dsqX9.mjs","names":[],"sources":["../src/commands/system.ts"],"sourcesContent":["import type { KiwiVMClient } from \"../client.ts\";\n\nexport async function run(\n action: string,\n flags: Record<string, string>,\n client: KiwiVMClient,\n): Promise<unknown> {\n switch (action) {\n case \"hostname\":\n return client.call(\"setHostname\", { newHostname: flags[\"newHostname\"] });\n case \"rdns\":\n return client.call(\"setPTR\", { ip: flags[\"ip\"], ptr: flags[\"ptr\"] });\n case \"password\":\n return client.call(\"resetRootPassword\");\n case \"sshkey\":\n if (flags[\"sshKeys\"] !== undefined) {\n return client.call(\"updateSshKeys\", { sshKeys: flags[\"sshKeys\"] });\n }\n return client.call(\"getSshKeys\");\n case \"os\":\n return client.call(\"getAvailableOS\");\n case \"reinstall\":\n return client.call(\"reinstallOS\", { os: flags[\"os\"] });\n default:\n throw new Error(\n `Unknown system action: ${action}. Valid: hostname, rdns, password, sshkey, os, reinstall`,\n );\n }\n}\n"],"mappings":";AAEA,eAAsB,IACpB,QACA,OACA,QACkB;AAClB,SAAQ,QAAR;EACE,KAAK,WACH,QAAO,OAAO,KAAK,eAAe,EAAE,aAAa,MAAM,gBAAgB,CAAC;EAC1E,KAAK,OACH,QAAO,OAAO,KAAK,UAAU;GAAE,IAAI,MAAM;GAAO,KAAK,MAAM;GAAQ,CAAC;EACtE,KAAK,WACH,QAAO,OAAO,KAAK,oBAAoB;EACzC,KAAK;AACH,OAAI,MAAM,eAAe,KAAA,EACvB,QAAO,OAAO,KAAK,iBAAiB,EAAE,SAAS,MAAM,YAAY,CAAC;AAEpE,UAAO,OAAO,KAAK,aAAa;EAClC,KAAK,KACH,QAAO,OAAO,KAAK,iBAAiB;EACtC,KAAK,YACH,QAAO,OAAO,KAAK,eAAe,EAAE,IAAI,MAAM,OAAO,CAAC;EACxD,QACE,OAAM,IAAI,MACR,0BAA0B,OAAO,0DAClC"}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
import type { KiwiVMClient } from "../client.ts";
|
|
3
|
-
import { run } from "./monitoring.ts";
|
|
4
|
-
|
|
5
|
-
function mockClient() {
|
|
6
|
-
const call = vi.fn();
|
|
7
|
-
return { client: { call } as unknown as KiwiVMClient, call };
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
describe("monitoring command", () => {
|
|
11
|
-
describe("usage", () => {
|
|
12
|
-
it("calls getRawUsageStats", async () => {
|
|
13
|
-
const { client, call } = mockClient();
|
|
14
|
-
call.mockResolvedValueOnce({
|
|
15
|
-
error: 0,
|
|
16
|
-
data: [{ month: "2025-01", usage: 100 }],
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const result = await run("usage", {}, client);
|
|
20
|
-
|
|
21
|
-
expect(client.call).toHaveBeenCalledExactlyOnceWith("getRawUsageStats");
|
|
22
|
-
expect(result).toMatchObject({
|
|
23
|
-
data: [{ month: "2025-01", usage: 100 }],
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe("audit", () => {
|
|
29
|
-
it("calls getAuditLog", async () => {
|
|
30
|
-
const { client, call } = mockClient();
|
|
31
|
-
call.mockResolvedValueOnce({
|
|
32
|
-
error: 0,
|
|
33
|
-
logs: [{ timestamp: 1700000000, action: "restart" }],
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const result = await run("audit", {}, client);
|
|
37
|
-
|
|
38
|
-
expect(client.call).toHaveBeenCalledExactlyOnceWith("getAuditLog");
|
|
39
|
-
expect(result).toMatchObject({
|
|
40
|
-
logs: [{ timestamp: 1700000000, action: "restart" }],
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe("rate-limit", () => {
|
|
46
|
-
it("calls getRateLimitStatus", async () => {
|
|
47
|
-
const { client, call } = mockClient();
|
|
48
|
-
call.mockResolvedValueOnce({
|
|
49
|
-
error: 0,
|
|
50
|
-
remaining: 950,
|
|
51
|
-
limit: 1000,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const result = await run("rate-limit", {}, client);
|
|
55
|
-
|
|
56
|
-
expect(client.call).toHaveBeenCalledExactlyOnceWith("getRateLimitStatus");
|
|
57
|
-
expect(result).toMatchObject({ remaining: 950, limit: 1000 });
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("returns the complete API response", async () => {
|
|
62
|
-
const { client, call } = mockClient();
|
|
63
|
-
const apiResponse = {
|
|
64
|
-
error: 0,
|
|
65
|
-
remaining: 500,
|
|
66
|
-
limit: 1000,
|
|
67
|
-
reset: 1700000000,
|
|
68
|
-
};
|
|
69
|
-
call.mockResolvedValueOnce(apiResponse);
|
|
70
|
-
|
|
71
|
-
const result = await run("rate-limit", {}, client);
|
|
72
|
-
|
|
73
|
-
expect(result).toEqual(apiResponse);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("propagates errors from the client", async () => {
|
|
77
|
-
const { client, call } = mockClient();
|
|
78
|
-
call.mockRejectedValueOnce(new Error("Rate limited"));
|
|
79
|
-
|
|
80
|
-
await expect(run("audit", {}, client)).rejects.toThrow("Rate limited");
|
|
81
|
-
});
|
|
82
|
-
});
|