@ornncompute/cli 1.0.72 → 1.0.97
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 +55 -24
- package/package.json +4 -2
- package/src/admin-capacity-reservations.mjs +6 -13
- package/src/admin-command-handlers.mjs +2 -1
- package/src/admin-credits.mjs +1 -2
- package/src/admin-enrollment.mjs +22 -30
- package/src/admin-mutations.mjs +6 -56
- package/src/admin-node-diagnostics.mjs +3 -41
- package/src/admin-node-lifecycle.mjs +40 -160
- package/src/admin-node-sanitize.mjs +243 -0
- package/src/admin-shell.mjs +39 -32
- package/src/catalog-shell.mjs +6 -6
- package/src/evidence-commands.mjs +4 -6
- package/src/external-bucket-commands.mjs +76 -96
- package/src/interaction-runtime.mjs +5 -37
- package/src/kubernetes-commands.mjs +25 -183
- package/src/launch-mode-handlers.mjs +0 -1
- package/src/machine-reference.mjs +33 -56
- package/src/mount-commands.mjs +25 -131
- package/src/slurm-commands.mjs +13 -2
- package/src/storage-commands.mjs +2 -87
- package/src/vm-commands.mjs +48 -101
- package/vendor/api-client/commerce.js +743 -0
- package/vendor/capabilities/cli.js +7688 -7
- package/vendor/capabilities/capabilities/admin-capacity-reservations.js +0 -101
- package/vendor/capabilities/capabilities/admin-enrollment.js +0 -321
- package/vendor/capabilities/capabilities/admin-node-diagnostics.js +0 -88
- package/vendor/capabilities/capabilities/admin-nodes-lifecycle.js +0 -235
- package/vendor/capabilities/capabilities/admin.js +0 -91
- package/vendor/capabilities/capabilities/cli.js +0 -156
- package/vendor/capabilities/capabilities/clusters.js +0 -248
- package/vendor/capabilities/capabilities/commerce-market.js +0 -405
- package/vendor/capabilities/capabilities/compute.js +0 -523
- package/vendor/capabilities/capabilities/credits.js +0 -78
- package/vendor/capabilities/capabilities/evidence.js +0 -145
- package/vendor/capabilities/capabilities/external-buckets.js +0 -191
- package/vendor/capabilities/capabilities/fleet.js +0 -306
- package/vendor/capabilities/capabilities/identity.js +0 -129
- package/vendor/capabilities/capabilities/listings.js +0 -398
- package/vendor/capabilities/capabilities/locality.js +0 -42
- package/vendor/capabilities/capabilities/market-shared.js +0 -46
- package/vendor/capabilities/capabilities/markets.js +0 -482
- package/vendor/capabilities/capabilities/mounts.js +0 -176
- package/vendor/capabilities/capabilities/native-listing.js +0 -99
- package/vendor/capabilities/capabilities/networks.js +0 -1264
- package/vendor/capabilities/capabilities/observability.js +0 -218
- package/vendor/capabilities/capabilities/organization-invites.js +0 -53
- package/vendor/capabilities/capabilities/reservation-list.js +0 -68
- package/vendor/capabilities/capabilities/staff-shared.js +0 -64
- package/vendor/capabilities/capabilities/tokens.js +0 -165
- package/vendor/capabilities/capabilities/users.js +0 -159
- package/vendor/capabilities/capabilities/volumes.js +0 -178
- package/vendor/capabilities/capability.js +0 -99
- package/vendor/capabilities/cli-catalog.js +0 -73
- package/vendor/capabilities/cli-migrations.js +0 -264
- package/vendor/capabilities/names.js +0 -6
- package/vendor/capabilities/software-catalog.js +0 -82
- package/vendor/capabilities/spec-catalog.js +0 -151
- package/vendor/capabilities/supplier-directory.js +0 -20
|
@@ -1,523 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { defineCapability, } from "../capability.js";
|
|
3
|
-
const positionals = z.array(z.string()).default([]);
|
|
4
|
-
export const launchInput = z
|
|
5
|
-
.object({
|
|
6
|
-
$positionals: positionals,
|
|
7
|
-
guided: z.boolean().optional(),
|
|
8
|
-
idempotencyKey: z.string().optional(),
|
|
9
|
-
key: z.string().optional(),
|
|
10
|
-
keyId: z.string().optional(),
|
|
11
|
-
label: z.string().optional(),
|
|
12
|
-
machine: z.string().optional(),
|
|
13
|
-
machines: z.string().optional(),
|
|
14
|
-
mode: z.string().optional(),
|
|
15
|
-
mountAccess: z.string().optional(),
|
|
16
|
-
network: z.string().optional(),
|
|
17
|
-
noWait: z.boolean().optional(),
|
|
18
|
-
nodes: z.union([z.string(), z.number()]).optional(),
|
|
19
|
-
publicKey: z.string().optional(),
|
|
20
|
-
publicKeyFile: z.string().optional(),
|
|
21
|
-
reservation: z.string().optional(),
|
|
22
|
-
resume: z.union([z.string().min(1), z.literal(true)]).optional(),
|
|
23
|
-
timeout: z.string().optional(),
|
|
24
|
-
username: z.string().optional(),
|
|
25
|
-
vms: z.string().optional(),
|
|
26
|
-
wait: z.boolean().optional(),
|
|
27
|
-
yes: z.boolean().optional(),
|
|
28
|
-
volume: z.string().optional(),
|
|
29
|
-
})
|
|
30
|
-
.strict();
|
|
31
|
-
const keyListInput = z
|
|
32
|
-
.object({
|
|
33
|
-
$positionals: positionals,
|
|
34
|
-
cursor: z.string().optional(),
|
|
35
|
-
limit: z.coerce.number().int().min(1).max(500).optional(),
|
|
36
|
-
})
|
|
37
|
-
.strict();
|
|
38
|
-
const keyMutationInput = z
|
|
39
|
-
.object({
|
|
40
|
-
$positionals: positionals,
|
|
41
|
-
idempotencyKey: z.string().optional(),
|
|
42
|
-
key: z.string().optional(),
|
|
43
|
-
keyId: z.string().optional(),
|
|
44
|
-
label: z.string().optional(),
|
|
45
|
-
publicKey: z.string().optional(),
|
|
46
|
-
publicKeyFile: z.string().optional(),
|
|
47
|
-
yes: z.boolean().optional(),
|
|
48
|
-
})
|
|
49
|
-
.strict();
|
|
50
|
-
const machineListInput = z
|
|
51
|
-
.object({
|
|
52
|
-
$positionals: positionals,
|
|
53
|
-
cursor: z.string().optional(),
|
|
54
|
-
limit: z.coerce.number().int().min(1).max(500).optional(),
|
|
55
|
-
})
|
|
56
|
-
.strict();
|
|
57
|
-
const machineShowInput = z
|
|
58
|
-
.object({
|
|
59
|
-
$positionals: positionals,
|
|
60
|
-
guided: z.boolean().optional(),
|
|
61
|
-
})
|
|
62
|
-
.strict();
|
|
63
|
-
const machineWaitInput = z
|
|
64
|
-
.object({
|
|
65
|
-
$positionals: positionals,
|
|
66
|
-
guided: z.boolean().optional(),
|
|
67
|
-
timeout: z.string().optional(),
|
|
68
|
-
})
|
|
69
|
-
.strict();
|
|
70
|
-
const machineSwitchInput = z
|
|
71
|
-
.object({
|
|
72
|
-
$positionals: positionals,
|
|
73
|
-
guided: z.boolean().optional(),
|
|
74
|
-
eraseLocalData: z.boolean().optional(),
|
|
75
|
-
idempotencyKey: z.string().optional(),
|
|
76
|
-
mode: z.string().optional(),
|
|
77
|
-
network: z.string().optional(),
|
|
78
|
-
noWait: z.boolean().optional(),
|
|
79
|
-
timeout: z.string().optional(),
|
|
80
|
-
wait: z.boolean().optional(),
|
|
81
|
-
yes: z.boolean().optional(),
|
|
82
|
-
})
|
|
83
|
-
.strict();
|
|
84
|
-
const machineMaintenanceInput = z
|
|
85
|
-
.object({
|
|
86
|
-
$positionals: positionals,
|
|
87
|
-
eraseLocalData: z.boolean().optional(),
|
|
88
|
-
guided: z.boolean().optional(),
|
|
89
|
-
idempotencyKey: z.string().optional(),
|
|
90
|
-
noWait: z.boolean().optional(),
|
|
91
|
-
timeout: z.string().optional(),
|
|
92
|
-
wait: z.boolean().optional(),
|
|
93
|
-
yes: z.boolean().optional(),
|
|
94
|
-
})
|
|
95
|
-
.strict();
|
|
96
|
-
function runtime(context) {
|
|
97
|
-
const interaction = context.cli?.interaction;
|
|
98
|
-
if (!interaction)
|
|
99
|
-
throw new Error("This capability must execute through the Ornn CLI runtime.");
|
|
100
|
-
return interaction;
|
|
101
|
-
}
|
|
102
|
-
async function executeLaunch(context, input) {
|
|
103
|
-
const interaction = runtime(context);
|
|
104
|
-
if (!interaction.launch)
|
|
105
|
-
throw new Error("No launch mode handlers are registered.");
|
|
106
|
-
return interaction.launch({ context, input, interaction });
|
|
107
|
-
}
|
|
108
|
-
function executeSshKeys(command) {
|
|
109
|
-
return async (context, input) => {
|
|
110
|
-
const interaction = runtime(context);
|
|
111
|
-
if (!interaction.sshKeys)
|
|
112
|
-
throw new Error("SSH-key commands are unavailable.");
|
|
113
|
-
return interaction.sshKeys(command, input, context);
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
function executeMachines(command) {
|
|
117
|
-
return async (context, input) => {
|
|
118
|
-
const interaction = runtime(context);
|
|
119
|
-
if (!interaction.machines)
|
|
120
|
-
throw new Error("Machine commands are unavailable.");
|
|
121
|
-
return interaction.machines(command, input, context);
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
function cliOnly(specification) {
|
|
125
|
-
return defineCapability({ ...specification, mcp: false, slack: false });
|
|
126
|
-
}
|
|
127
|
-
export const launchCapability = cliOnly({
|
|
128
|
-
id: "access.launch",
|
|
129
|
-
domain: "access",
|
|
130
|
-
roles: ["user"],
|
|
131
|
-
description: "Launch one explicitly selected access mode from active reserved capacity.",
|
|
132
|
-
mutation: "preview-confirm",
|
|
133
|
-
input: launchInput,
|
|
134
|
-
cli: {
|
|
135
|
-
command: ["launch"],
|
|
136
|
-
vnext: {
|
|
137
|
-
arguments: "semantic",
|
|
138
|
-
audience: "customer",
|
|
139
|
-
category: "journey",
|
|
140
|
-
order: 2,
|
|
141
|
-
outcome: "Launch one reviewed VM, Bare Metal machine, Kubernetes cluster, or Slurm cluster from active reserved capacity, including a declared durable Bare Metal workspace.",
|
|
142
|
-
human: "ornn launch [<capacity-reservation>] --mode vm|bare-metal|kubernetes|slurm [--key <ssh-key>]; Bare Metal may add --network shared --volume <managed-volume> --mount-access read-only|read-write; Kubernetes/Slurm prompt for missing --network public|private and --nodes <membership-count>, and may add running VMs with --vms <vm-ids>",
|
|
143
|
-
automation: "ornn launch <canonical-reservation-id> --mode vm|bare-metal|kubernetes|slurm --yes --idempotency-key <key> --format json; VM/Bare Metal/Slurm require --key <canonical-key-id>; Bare Metal may add --network shared --volume <canonical-volume-id> --mount-access read-only|read-write; Kubernetes/Slurm require --network public|private --nodes <membership-count> --machines <canonical-machine-ids>, and may add --vms <canonical-vm-ids> (with --nodes 0 for a cluster of VMs only)",
|
|
144
|
-
acceptedReferences: [
|
|
145
|
-
"canonical capacity-reservation ID",
|
|
146
|
-
"canonical eligible machine IDs",
|
|
147
|
-
"canonical running VM IDs for cluster membership",
|
|
148
|
-
"invocation-local eligible reservation and machine choices",
|
|
149
|
-
"exact SSH-key and managed-volume references; organization network shared",
|
|
150
|
-
],
|
|
151
|
-
review: "organization, active capacity reservation, explicit access mode, native access, exact machine or cluster membership goal, declared SSH key, network and volume-mount relationships, allocation window and quantity, and wait behavior",
|
|
152
|
-
resumableStates: [
|
|
153
|
-
"partial durable workspace",
|
|
154
|
-
"accepted machine or cluster",
|
|
155
|
-
"native access ready",
|
|
156
|
-
"partial membership",
|
|
157
|
-
],
|
|
158
|
-
related: [
|
|
159
|
-
"connect",
|
|
160
|
-
"machines list",
|
|
161
|
-
"clusters show",
|
|
162
|
-
"volume-mounts show",
|
|
163
|
-
"filesystems show",
|
|
164
|
-
"ssh-keys list",
|
|
165
|
-
"ssh-keys assignments status",
|
|
166
|
-
],
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
execute: executeLaunch,
|
|
170
|
-
});
|
|
171
|
-
export const machineListCapability = cliOnly({
|
|
172
|
-
id: "access.machines.list",
|
|
173
|
-
domain: "access",
|
|
174
|
-
roles: ["user"],
|
|
175
|
-
description: "List direct VM and Bare Metal machines in one bounded page.",
|
|
176
|
-
mutation: "read",
|
|
177
|
-
input: machineListInput,
|
|
178
|
-
cli: {
|
|
179
|
-
command: ["machines", "list"],
|
|
180
|
-
vnext: {
|
|
181
|
-
arguments: "semantic",
|
|
182
|
-
audience: "customer",
|
|
183
|
-
category: "resource",
|
|
184
|
-
order: 460,
|
|
185
|
-
outcome: "List owned direct machines with lifecycle and SSH reachability kept separate.",
|
|
186
|
-
human: "ornn machines list [--limit <1-500>] [--cursor <opaque-cursor>]",
|
|
187
|
-
automation: "ornn machines list --limit 50 --format json",
|
|
188
|
-
acceptedReferences: ["opaque page cursor"],
|
|
189
|
-
related: ["machines show", "machines wait"],
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
execute: executeMachines("list"),
|
|
193
|
-
});
|
|
194
|
-
export const machineShowCapability = cliOnly({
|
|
195
|
-
id: "access.machines.show",
|
|
196
|
-
domain: "access",
|
|
197
|
-
roles: ["user"],
|
|
198
|
-
description: "Inspect one exact direct machine without changing it.",
|
|
199
|
-
mutation: "read",
|
|
200
|
-
input: machineShowInput,
|
|
201
|
-
cli: {
|
|
202
|
-
command: ["machines", "show"],
|
|
203
|
-
vnext: {
|
|
204
|
-
arguments: "semantic",
|
|
205
|
-
audience: "customer",
|
|
206
|
-
category: "resource",
|
|
207
|
-
order: 461,
|
|
208
|
-
outcome: "Show one exact VM or Bare Metal machine, its lifecycle, and independent SSH reachability.",
|
|
209
|
-
human: "ornn machines show <canonical-machine-id|exact-hostname>",
|
|
210
|
-
automation: "ornn machines show <canonical-machine-id> --format json",
|
|
211
|
-
acceptedReferences: [
|
|
212
|
-
"canonical machine ID",
|
|
213
|
-
"exact unique hostname",
|
|
214
|
-
"invocation-local guided choice",
|
|
215
|
-
],
|
|
216
|
-
related: ["connect", "machines wait"],
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
execute: executeMachines("show"),
|
|
220
|
-
});
|
|
221
|
-
export const machineWaitCapability = cliOnly({
|
|
222
|
-
id: "access.machines.wait",
|
|
223
|
-
domain: "access",
|
|
224
|
-
roles: ["user"],
|
|
225
|
-
description: "Wait locally for one exact direct machine to become SSH-ready.",
|
|
226
|
-
mutation: "read",
|
|
227
|
-
input: machineWaitInput,
|
|
228
|
-
cli: {
|
|
229
|
-
command: ["machines", "wait"],
|
|
230
|
-
vnext: {
|
|
231
|
-
arguments: "semantic",
|
|
232
|
-
audience: "customer",
|
|
233
|
-
category: "resource",
|
|
234
|
-
order: 462,
|
|
235
|
-
outcome: "Wait for usable SSH without canceling remote work on timeout or interruption.",
|
|
236
|
-
human: "ornn machines wait <canonical-machine-id|exact-hostname> [--timeout <duration>]",
|
|
237
|
-
automation: "ornn machines wait <canonical-machine-id> --timeout <duration> --format json",
|
|
238
|
-
acceptedReferences: [
|
|
239
|
-
"canonical machine ID",
|
|
240
|
-
"exact unique hostname",
|
|
241
|
-
"invocation-local guided choice",
|
|
242
|
-
],
|
|
243
|
-
resumableStates: ["provisioning", "SSH-key delivery pending", "SSH ready"],
|
|
244
|
-
related: ["machines show", "connect"],
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
execute: executeMachines("wait"),
|
|
248
|
-
});
|
|
249
|
-
export const machineSwitchCapability = cliOnly({
|
|
250
|
-
id: "access.machines.switch",
|
|
251
|
-
domain: "access",
|
|
252
|
-
roles: ["user"],
|
|
253
|
-
description: "Switch one direct-machine reservation's mode or network intent.",
|
|
254
|
-
mutation: "preview-confirm",
|
|
255
|
-
input: machineSwitchInput,
|
|
256
|
-
cli: {
|
|
257
|
-
command: ["machines", "switch"],
|
|
258
|
-
vnext: {
|
|
259
|
-
arguments: "semantic",
|
|
260
|
-
audience: "customer",
|
|
261
|
-
category: "resource",
|
|
262
|
-
order: 463,
|
|
263
|
-
outcome: "Change only the explicitly requested VM, Bare Metal, or network goal while retaining SSH-key intent.",
|
|
264
|
-
human: "ornn machines switch <canonical-reservation-id> [--mode vm|bare-metal] [--network public|private] [--erase-local-data]",
|
|
265
|
-
automation: "ornn machines switch <canonical-reservation-id> [--mode vm|bare-metal] [--network public|private] [--erase-local-data] --yes --idempotency-key <key> --format json",
|
|
266
|
-
acceptedReferences: ["canonical capacity-reservation ID"],
|
|
267
|
-
review: "exact reservation, current and requested access mode, network intent, retained SSH keys, access interruption, and permanent local-data erasure for cross-mode changes",
|
|
268
|
-
resumableStates: ["switch accepted", "SSH ready"],
|
|
269
|
-
related: ["machines wait", "connect"],
|
|
270
|
-
},
|
|
271
|
-
},
|
|
272
|
-
execute: executeMachines("switch"),
|
|
273
|
-
});
|
|
274
|
-
export const machineRebootCapability = cliOnly({
|
|
275
|
-
id: "access.machines.reboot",
|
|
276
|
-
domain: "access",
|
|
277
|
-
roles: ["user"],
|
|
278
|
-
description: "Reboot one exact direct machine after reviewing the access interruption.",
|
|
279
|
-
mutation: "preview-confirm",
|
|
280
|
-
input: machineMaintenanceInput,
|
|
281
|
-
cli: {
|
|
282
|
-
command: ["machines", "reboot"],
|
|
283
|
-
vnext: {
|
|
284
|
-
arguments: "semantic",
|
|
285
|
-
audience: "customer",
|
|
286
|
-
category: "resource",
|
|
287
|
-
order: 464,
|
|
288
|
-
outcome: "Reboot one exact machine and normally wait for restored SSH readiness.",
|
|
289
|
-
human: "ornn machines reboot <canonical-machine-id|exact-hostname> [--no-wait]",
|
|
290
|
-
automation: "ornn machines reboot <canonical-machine-id> --yes --idempotency-key <key> --format json",
|
|
291
|
-
acceptedReferences: [
|
|
292
|
-
"canonical machine ID",
|
|
293
|
-
"exact unique hostname",
|
|
294
|
-
"invocation-local guided choice",
|
|
295
|
-
],
|
|
296
|
-
review: "temporary SSH interruption with SSH keys, network, mounted volume, and local data preserved",
|
|
297
|
-
resumableStates: ["reboot accepted", "SSH ready"],
|
|
298
|
-
related: ["machines wait", "connect"],
|
|
299
|
-
},
|
|
300
|
-
},
|
|
301
|
-
execute: executeMachines("reboot"),
|
|
302
|
-
});
|
|
303
|
-
export const machineResetCapability = cliOnly({
|
|
304
|
-
id: "access.machines.reset",
|
|
305
|
-
domain: "access",
|
|
306
|
-
roles: ["user"],
|
|
307
|
-
description: "Erase local machine data and hard reset one exact direct machine.",
|
|
308
|
-
mutation: "preview-confirm",
|
|
309
|
-
input: machineMaintenanceInput,
|
|
310
|
-
cli: {
|
|
311
|
-
command: ["machines", "reset"],
|
|
312
|
-
vnext: {
|
|
313
|
-
arguments: "semantic",
|
|
314
|
-
audience: "customer",
|
|
315
|
-
category: "resource",
|
|
316
|
-
order: 465,
|
|
317
|
-
outcome: "Hard reset one exact machine only with explicit local-data erasure scope and final consent.",
|
|
318
|
-
human: "ornn machines reset <canonical-machine-id|exact-hostname> --erase-local-data [--no-wait]",
|
|
319
|
-
automation: "ornn machines reset <canonical-machine-id> --erase-local-data --yes --idempotency-key <key> --format json",
|
|
320
|
-
acceptedReferences: [
|
|
321
|
-
"canonical machine ID",
|
|
322
|
-
"exact unique hostname",
|
|
323
|
-
"invocation-local guided choice",
|
|
324
|
-
],
|
|
325
|
-
review: "permanent local-data erasure, temporary access interruption, restored SSH keys, and preserved external volume relationship",
|
|
326
|
-
resumableStates: ["reset accepted", "SSH ready"],
|
|
327
|
-
related: ["machines wait", "connect"],
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
execute: executeMachines("reset"),
|
|
331
|
-
});
|
|
332
|
-
export const sshKeyListCapability = cliOnly({
|
|
333
|
-
id: "access.ssh_keys.list",
|
|
334
|
-
domain: "access",
|
|
335
|
-
roles: ["user"],
|
|
336
|
-
mutation: "read",
|
|
337
|
-
input: keyListInput,
|
|
338
|
-
description: "List organization SSH keys in a bounded page.",
|
|
339
|
-
cli: {
|
|
340
|
-
command: ["ssh-keys", "list"],
|
|
341
|
-
vnext: {
|
|
342
|
-
arguments: "semantic",
|
|
343
|
-
audience: "customer",
|
|
344
|
-
category: "resource",
|
|
345
|
-
order: 450,
|
|
346
|
-
outcome: "List organization SSH keys without exposing key material.",
|
|
347
|
-
human: "ornn ssh-keys list [--limit <1-500>] [--cursor <cursor>]",
|
|
348
|
-
automation: "ornn ssh-keys list --format json [--limit <1-500>] [--cursor <cursor>]",
|
|
349
|
-
acceptedReferences: [],
|
|
350
|
-
related: ["ssh-keys add", "ssh-keys assignments list"],
|
|
351
|
-
},
|
|
352
|
-
},
|
|
353
|
-
execute: executeSshKeys("list"),
|
|
354
|
-
});
|
|
355
|
-
export const sshKeyAddCapability = cliOnly({
|
|
356
|
-
id: "access.ssh_keys.add",
|
|
357
|
-
domain: "access",
|
|
358
|
-
roles: ["user"],
|
|
359
|
-
mutation: "preview-confirm",
|
|
360
|
-
input: keyMutationInput,
|
|
361
|
-
description: "Add or replay one organization SSH public key.",
|
|
362
|
-
cli: {
|
|
363
|
-
command: ["ssh-keys", "add"],
|
|
364
|
-
vnext: {
|
|
365
|
-
arguments: "semantic",
|
|
366
|
-
audience: "customer",
|
|
367
|
-
category: "resource",
|
|
368
|
-
order: 451,
|
|
369
|
-
outcome: "Add one organization SSH public key by durable public-key identity.",
|
|
370
|
-
human: "ornn ssh-keys add --public-key-file <path> --label <label>",
|
|
371
|
-
automation: "ornn ssh-keys add --public-key <public-key> --label <label> --idempotency-key <key> --format json",
|
|
372
|
-
acceptedReferences: ["public key value", "public key file"],
|
|
373
|
-
resumableStates: ["ready"],
|
|
374
|
-
related: ["ssh-keys list", "ssh-keys assignments assign"],
|
|
375
|
-
},
|
|
376
|
-
},
|
|
377
|
-
execute: executeSshKeys("add"),
|
|
378
|
-
});
|
|
379
|
-
export const sshKeyDeleteCapability = cliOnly({
|
|
380
|
-
id: "access.ssh_keys.delete",
|
|
381
|
-
domain: "access",
|
|
382
|
-
roles: ["user"],
|
|
383
|
-
mutation: "preview-confirm",
|
|
384
|
-
input: keyMutationInput,
|
|
385
|
-
description: "Delete one exact organization SSH key after review.",
|
|
386
|
-
cli: {
|
|
387
|
-
command: ["ssh-keys", "delete"],
|
|
388
|
-
vnext: {
|
|
389
|
-
arguments: "semantic",
|
|
390
|
-
audience: "customer",
|
|
391
|
-
category: "resource",
|
|
392
|
-
order: 452,
|
|
393
|
-
outcome: "Delete one exact organization SSH key without implying machine delivery.",
|
|
394
|
-
human: "ornn ssh-keys delete <exact-key-id-or-label>",
|
|
395
|
-
automation: "ornn ssh-keys delete <canonical-key-id> --yes --idempotency-key <key> --format json",
|
|
396
|
-
acceptedReferences: [
|
|
397
|
-
"canonical SSH-key ID",
|
|
398
|
-
"exact unique key label in an eligible terminal",
|
|
399
|
-
],
|
|
400
|
-
review: "key identity and loss of future access",
|
|
401
|
-
resumableStates: ["ended"],
|
|
402
|
-
related: ["ssh-keys list"],
|
|
403
|
-
},
|
|
404
|
-
},
|
|
405
|
-
execute: executeSshKeys("delete"),
|
|
406
|
-
});
|
|
407
|
-
export const sshKeyAssignmentListCapability = cliOnly({
|
|
408
|
-
id: "access.ssh_key_assignments.list",
|
|
409
|
-
domain: "access",
|
|
410
|
-
roles: ["user"],
|
|
411
|
-
mutation: "read",
|
|
412
|
-
input: keyListInput,
|
|
413
|
-
description: "List SSH keys assigned to one capacity reservation.",
|
|
414
|
-
cli: {
|
|
415
|
-
command: ["ssh-keys", "assignments", "list"],
|
|
416
|
-
vnext: {
|
|
417
|
-
arguments: "semantic",
|
|
418
|
-
audience: "customer",
|
|
419
|
-
category: "resource",
|
|
420
|
-
order: 453,
|
|
421
|
-
outcome: "List the SSH keys assigned to one exact capacity reservation.",
|
|
422
|
-
human: "ornn ssh-keys assignments list <canonical-reservation-id>",
|
|
423
|
-
automation: "ornn ssh-keys assignments list <canonical-reservation-id> --format json",
|
|
424
|
-
acceptedReferences: ["canonical capacity-reservation ID"],
|
|
425
|
-
related: ["ssh-keys assignments status"],
|
|
426
|
-
},
|
|
427
|
-
},
|
|
428
|
-
execute: executeSshKeys("assignments.list"),
|
|
429
|
-
});
|
|
430
|
-
export const sshKeyAssignmentAssignCapability = cliOnly({
|
|
431
|
-
id: "access.ssh_key_assignments.assign",
|
|
432
|
-
domain: "access",
|
|
433
|
-
roles: ["user"],
|
|
434
|
-
mutation: "preview-confirm",
|
|
435
|
-
input: keyMutationInput,
|
|
436
|
-
description: "Assign one existing organization SSH key to one capacity reservation.",
|
|
437
|
-
cli: {
|
|
438
|
-
command: ["ssh-keys", "assignments", "assign"],
|
|
439
|
-
vnext: {
|
|
440
|
-
arguments: "semantic",
|
|
441
|
-
audience: "customer",
|
|
442
|
-
category: "resource",
|
|
443
|
-
order: 454,
|
|
444
|
-
outcome: "Assign or replay one exact SSH-key relationship.",
|
|
445
|
-
human: "ornn ssh-keys assignments assign <canonical-reservation-id> --key <exact-key-id-or-label>",
|
|
446
|
-
automation: "ornn ssh-keys assignments assign <canonical-reservation-id> --key <canonical-key-id> --yes --idempotency-key <key> --format json",
|
|
447
|
-
acceptedReferences: [
|
|
448
|
-
"canonical capacity-reservation ID",
|
|
449
|
-
"canonical SSH-key ID",
|
|
450
|
-
"exact unique key label in an eligible terminal",
|
|
451
|
-
],
|
|
452
|
-
review: "reservation and SSH-key relationship",
|
|
453
|
-
resumableStates: ["associated", "queued", "installed"],
|
|
454
|
-
related: ["ssh-keys assignments status"],
|
|
455
|
-
},
|
|
456
|
-
},
|
|
457
|
-
execute: executeSshKeys("assignments.assign"),
|
|
458
|
-
});
|
|
459
|
-
export const sshKeyAssignmentSyncCapability = cliOnly({
|
|
460
|
-
id: "access.ssh_key_assignments.sync",
|
|
461
|
-
domain: "access",
|
|
462
|
-
roles: ["user"],
|
|
463
|
-
mutation: "preview-confirm",
|
|
464
|
-
input: keyMutationInput,
|
|
465
|
-
description: "Synchronize assigned SSH keys to every active reservation machine.",
|
|
466
|
-
cli: {
|
|
467
|
-
command: ["ssh-keys", "assignments", "sync"],
|
|
468
|
-
vnext: {
|
|
469
|
-
arguments: "semantic",
|
|
470
|
-
audience: "customer",
|
|
471
|
-
category: "resource",
|
|
472
|
-
order: 455,
|
|
473
|
-
outcome: "Queue idempotent SSH-key synchronization and report delayed delivery honestly.",
|
|
474
|
-
human: "ornn ssh-keys assignments sync <canonical-reservation-id>",
|
|
475
|
-
automation: "ornn ssh-keys assignments sync <canonical-reservation-id> --yes --idempotency-key <key> --format json",
|
|
476
|
-
acceptedReferences: ["canonical capacity-reservation ID"],
|
|
477
|
-
review: "reservation, assigned keys, and target machines",
|
|
478
|
-
resumableStates: ["queued", "installed", "failed"],
|
|
479
|
-
related: ["ssh-keys assignments status"],
|
|
480
|
-
},
|
|
481
|
-
},
|
|
482
|
-
execute: executeSshKeys("assignments.sync"),
|
|
483
|
-
});
|
|
484
|
-
export const sshKeyAssignmentStatusCapability = cliOnly({
|
|
485
|
-
id: "access.ssh_key_assignments.status",
|
|
486
|
-
domain: "access",
|
|
487
|
-
roles: ["user"],
|
|
488
|
-
mutation: "read",
|
|
489
|
-
input: keyListInput,
|
|
490
|
-
description: "Show assigned, queued, installed, and failed SSH-key delivery per machine.",
|
|
491
|
-
cli: {
|
|
492
|
-
command: ["ssh-keys", "assignments", "status"],
|
|
493
|
-
vnext: {
|
|
494
|
-
arguments: "semantic",
|
|
495
|
-
audience: "customer",
|
|
496
|
-
category: "resource",
|
|
497
|
-
order: 456,
|
|
498
|
-
outcome: "Distinguish SSH-key assignment from delayed machine delivery.",
|
|
499
|
-
human: "ornn ssh-keys assignments status <canonical-reservation-id>",
|
|
500
|
-
automation: "ornn ssh-keys assignments status <canonical-reservation-id> --format json",
|
|
501
|
-
acceptedReferences: ["canonical capacity-reservation ID"],
|
|
502
|
-
resumableStates: ["associated", "queued", "installed", "failed"],
|
|
503
|
-
related: ["ssh-keys assignments sync", "connect"],
|
|
504
|
-
},
|
|
505
|
-
},
|
|
506
|
-
execute: executeSshKeys("assignments.status"),
|
|
507
|
-
});
|
|
508
|
-
export const computeCapabilities = [
|
|
509
|
-
launchCapability,
|
|
510
|
-
machineListCapability,
|
|
511
|
-
machineShowCapability,
|
|
512
|
-
machineWaitCapability,
|
|
513
|
-
machineSwitchCapability,
|
|
514
|
-
machineRebootCapability,
|
|
515
|
-
machineResetCapability,
|
|
516
|
-
sshKeyListCapability,
|
|
517
|
-
sshKeyAddCapability,
|
|
518
|
-
sshKeyDeleteCapability,
|
|
519
|
-
sshKeyAssignmentListCapability,
|
|
520
|
-
sshKeyAssignmentAssignCapability,
|
|
521
|
-
sshKeyAssignmentSyncCapability,
|
|
522
|
-
sshKeyAssignmentStatusCapability,
|
|
523
|
-
];
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { defineCapability, preview } from "../capability.js";
|
|
3
|
-
export const creditGrantInput = z.object({
|
|
4
|
-
organizationId: z
|
|
5
|
-
.uuid()
|
|
6
|
-
.describe("Customer organization UUID. Resolve names or emails with organization_list; ask which organization if matches are ambiguous."),
|
|
7
|
-
adjustmentId: z
|
|
8
|
-
.uuid()
|
|
9
|
-
.describe("The credit-adjustment API's required grant UUID. Keep the same UUID when confirming this grant."),
|
|
10
|
-
amountCents: z
|
|
11
|
-
.number()
|
|
12
|
-
.int()
|
|
13
|
-
.min(1)
|
|
14
|
-
.max(100_000_000)
|
|
15
|
-
.describe("USD cents: 10000 grants $100.00."),
|
|
16
|
-
note: z
|
|
17
|
-
.string()
|
|
18
|
-
.trim()
|
|
19
|
-
.min(1)
|
|
20
|
-
.refine((value) => new TextEncoder().encode(value).length <= 500, "Keep the note under 500 UTF-8 bytes.")
|
|
21
|
-
.describe("Reason for the credit grant."),
|
|
22
|
-
confirm: z.boolean().optional(),
|
|
23
|
-
});
|
|
24
|
-
export const creditGrantCapability = defineCapability({
|
|
25
|
-
id: "credits.grant",
|
|
26
|
-
domain: "billing",
|
|
27
|
-
roles: ["admin"],
|
|
28
|
-
description: "Grant Ornn credits to a customer organization using the same operation as Internal Billing. " +
|
|
29
|
-
"Credits belong to the organization, not an individual person. Resolve the intended organization first. " +
|
|
30
|
-
"Preview first; confirm:true posts the same grant with its adjustmentId. The verified staff actor supplies audit identity.",
|
|
31
|
-
mutation: "preview-confirm",
|
|
32
|
-
http: { method: "POST", path: "/internal/v1/organizations/{organizationId}/credit-adjustments" },
|
|
33
|
-
cli: {
|
|
34
|
-
command: ["admin", "organizations", "grant-credit"],
|
|
35
|
-
vnext: {
|
|
36
|
-
audience: "admin",
|
|
37
|
-
category: "resource",
|
|
38
|
-
command: ["admin", "organizations", "grant-credit"],
|
|
39
|
-
outcome: "Grant Ornn credits to a customer organization.",
|
|
40
|
-
human: "ornn admin organizations grant-credit --organization UUID --amount-cents N --note TEXT --idempotency-key UUID [--yes]",
|
|
41
|
-
automation: "Requires an eligible human terminal.",
|
|
42
|
-
acceptedReferences: ["organization UUID from admin organizations list"],
|
|
43
|
-
review: "Review the organization, USD amount, note, and grant UUID before default-no consent.",
|
|
44
|
-
related: ["admin organizations list", "admin users list"],
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
slack: {
|
|
48
|
-
parameters: {
|
|
49
|
-
type: "object",
|
|
50
|
-
properties: {
|
|
51
|
-
organizationId: {
|
|
52
|
-
type: "string",
|
|
53
|
-
format: "uuid",
|
|
54
|
-
description: "Exact customer organization UUID from organization_list.",
|
|
55
|
-
},
|
|
56
|
-
amountCents: {
|
|
57
|
-
type: "integer",
|
|
58
|
-
minimum: 1,
|
|
59
|
-
maximum: 100_000_000,
|
|
60
|
-
description: "USD cents: 10000 grants $100.00.",
|
|
61
|
-
},
|
|
62
|
-
note: {
|
|
63
|
-
type: "string",
|
|
64
|
-
description: "Reason for the credit grant, at most 500 UTF-8 bytes.",
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
required: ["organizationId", "amountCents", "note"],
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
input: creditGrantInput,
|
|
71
|
-
execute: async (ctx, input) => {
|
|
72
|
-
const { organizationId, confirm: _confirm, ...grant } = creditGrantInput.parse(input);
|
|
73
|
-
const body = { ...grant, direction: "credit" };
|
|
74
|
-
if (!ctx.confirmed)
|
|
75
|
-
return preview("credits.grant", { organizationId, ...body });
|
|
76
|
-
return ctx.fetch(`/internal/v1/organizations/${encodeURIComponent(organizationId)}/credit-adjustments`, { method: "POST", body });
|
|
77
|
-
},
|
|
78
|
-
});
|