gigadrive 2.15.0 → 2.17.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/dist/index.cjs +84 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +84 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -32,7 +32,7 @@ var import_effect31 = require("effect");
|
|
|
32
32
|
// package.json
|
|
33
33
|
var package_default = {
|
|
34
34
|
name: "gigadrive",
|
|
35
|
-
version: "2.
|
|
35
|
+
version: "2.17.0",
|
|
36
36
|
repository: {
|
|
37
37
|
type: "git",
|
|
38
38
|
url: "https://github.com/Gigadrive/sdk.git",
|
|
@@ -3073,6 +3073,7 @@ var describeMicroVm = (vm, now = Date.now()) => {
|
|
|
3073
3073
|
`Size: ${vm.vcpus} vCPU, ${formatMemory(vm.memoryMb)} memory, ${formatMemory(vm.diskMb)} disk`,
|
|
3074
3074
|
`Region: ${vm.region}`,
|
|
3075
3075
|
`Network: ${vm.network.egress === "deny" ? "outbound traffic blocked" : vm.network.allow && vm.network.allow.length > 0 ? `only ${vm.network.allow.join(", ")}` : "internet access"}`,
|
|
3076
|
+
...(vm.network.inject ?? []).map((rule) => `Injects: ${rule.headers.join(", ")} for ${rule.domain}`),
|
|
3076
3077
|
`Previews: ${vm.network.previews === "private" ? "private (preview token required)" : "public"}`,
|
|
3077
3078
|
`Application: ${vm.applicationId}`,
|
|
3078
3079
|
`Created: ${vm.createdAt}`
|
|
@@ -3383,6 +3384,37 @@ var parseVolumeFlags = (values) => import_effect24.Effect.gen(function* () {
|
|
|
3383
3384
|
}
|
|
3384
3385
|
return volumes;
|
|
3385
3386
|
});
|
|
3387
|
+
var parseInjectFlags = (values) => import_effect24.Effect.gen(function* () {
|
|
3388
|
+
const rules = /* @__PURE__ */ new Map();
|
|
3389
|
+
for (const value of values) {
|
|
3390
|
+
const colon = value.indexOf(":");
|
|
3391
|
+
const equals = value.indexOf("=", colon + 1);
|
|
3392
|
+
const domain = colon > 0 ? value.slice(0, colon).trim().toLowerCase() : "";
|
|
3393
|
+
const name = colon > 0 && equals > colon ? value.slice(colon + 1, equals).trim() : "";
|
|
3394
|
+
if (domain === "" || name === "" || equals === value.length - 1) {
|
|
3395
|
+
return yield* new InvalidMicroVmOptionsError({
|
|
3396
|
+
// The entry is not echoed: it may hold the credential.
|
|
3397
|
+
message: '--inject and --inject-file take DOMAIN:HEADER=VALUE, such as "api.openai.com:Authorization=Bearer $OPENAI_API_KEY".'
|
|
3398
|
+
});
|
|
3399
|
+
}
|
|
3400
|
+
rules.set(domain, { ...rules.get(domain), [name]: value.slice(equals + 1) });
|
|
3401
|
+
}
|
|
3402
|
+
if (rules.size > 8) {
|
|
3403
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--inject takes at most 8 domains." });
|
|
3404
|
+
}
|
|
3405
|
+
return [...rules].map(([domain, headers]) => ({ domain, headers }));
|
|
3406
|
+
});
|
|
3407
|
+
var readInjectRules = (inject, injectFile) => import_effect24.Effect.gen(function* () {
|
|
3408
|
+
if (import_effect24.Option.isNone(injectFile)) return yield* parseInjectFlags(inject);
|
|
3409
|
+
const fs = yield* import_platform8.FileSystem.FileSystem;
|
|
3410
|
+
const content = yield* fs.readFileString(injectFile.value).pipe(
|
|
3411
|
+
import_effect24.Effect.mapError(
|
|
3412
|
+
() => new InvalidMicroVmOptionsError({ message: `Could not read --inject-file ${injectFile.value}.` })
|
|
3413
|
+
)
|
|
3414
|
+
);
|
|
3415
|
+
const lines = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#"));
|
|
3416
|
+
return yield* parseInjectFlags([...inject, ...lines]);
|
|
3417
|
+
});
|
|
3386
3418
|
var checkEgressFlags = (denyEgress, allowEgress) => import_effect24.Effect.gen(function* () {
|
|
3387
3419
|
if (denyEgress && allowEgress.length > 0) {
|
|
3388
3420
|
return yield* new InvalidMicroVmOptionsError({
|
|
@@ -3413,6 +3445,10 @@ var createInput = (flags) => import_effect24.Effect.gen(function* () {
|
|
|
3413
3445
|
if (badPort !== void 0) {
|
|
3414
3446
|
return yield* new InvalidMicroVmOptionsError({ message: `--port must be between 1 and 65535 (got ${badPort}).` });
|
|
3415
3447
|
}
|
|
3448
|
+
const inject = yield* readInjectRules(flags.inject, flags.injectFile);
|
|
3449
|
+
if (inject.length > 0 && flags.denyEgress) {
|
|
3450
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--inject cannot be combined with --deny-egress." });
|
|
3451
|
+
}
|
|
3416
3452
|
const volumes = yield* parseVolumeFlags(flags.volumes);
|
|
3417
3453
|
if (volumes.length > 0 && flags.pauseOnTimeout) {
|
|
3418
3454
|
return yield* new InvalidMicroVmOptionsError({ message: "--volume cannot be combined with --pause-on-timeout." });
|
|
@@ -3434,11 +3470,12 @@ var createInput = (flags) => import_effect24.Effect.gen(function* () {
|
|
|
3434
3470
|
...env ? { env } : {},
|
|
3435
3471
|
...metadata ? { metadata } : {},
|
|
3436
3472
|
...volumes.length > 0 ? { volumes } : {},
|
|
3437
|
-
...flags.denyEgress || flags.privatePreviews || flags.allowEgress.length > 0 ? {
|
|
3473
|
+
...flags.denyEgress || flags.privatePreviews || flags.allowEgress.length > 0 || inject.length > 0 ? {
|
|
3438
3474
|
network: {
|
|
3439
3475
|
egress: flags.denyEgress ? "deny" : "allow",
|
|
3440
3476
|
...flags.privatePreviews ? { previews: "private" } : {},
|
|
3441
|
-
...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {}
|
|
3477
|
+
...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {},
|
|
3478
|
+
...inject.length > 0 ? { inject } : {}
|
|
3442
3479
|
}
|
|
3443
3480
|
} : {},
|
|
3444
3481
|
...import_effect24.Option.match(flags.region, { onNone: () => ({}), onSome: (region) => ({ region }) })
|
|
@@ -3529,6 +3566,18 @@ var createCommand = import_cli12.Command.make(
|
|
|
3529
3566
|
),
|
|
3530
3567
|
import_cli12.Options.repeated
|
|
3531
3568
|
),
|
|
3569
|
+
inject: import_cli12.Options.text("inject").pipe(
|
|
3570
|
+
import_cli12.Options.withDescription(
|
|
3571
|
+
"Add a header to HTTPS requests to a domain, as DOMAIN:HEADER=VALUE (repeatable, up to 8 domains); the value never enters the microVM"
|
|
3572
|
+
),
|
|
3573
|
+
import_cli12.Options.repeated
|
|
3574
|
+
),
|
|
3575
|
+
injectFile: import_cli12.Options.text("inject-file").pipe(
|
|
3576
|
+
import_cli12.Options.withDescription(
|
|
3577
|
+
"Read --inject rules from a file, one DOMAIN:HEADER=VALUE per line (/dev/stdin for a pipe), so the values stay out of the command line"
|
|
3578
|
+
),
|
|
3579
|
+
import_cli12.Options.optional
|
|
3580
|
+
),
|
|
3532
3581
|
pauseOnTimeout: import_cli12.Options.boolean("pause-on-timeout").pipe(
|
|
3533
3582
|
import_cli12.Options.withDescription("Pause the microVM when its timeout ends instead of stopping it")
|
|
3534
3583
|
),
|
|
@@ -3898,15 +3947,31 @@ var updateMicroVmNetwork = (microvmId, flags) => import_effect24.Effect.gen(func
|
|
|
3898
3947
|
});
|
|
3899
3948
|
}
|
|
3900
3949
|
yield* checkEgressFlags(flags.denyEgress, flags.allowEgress);
|
|
3950
|
+
const inject = yield* readInjectRules(flags.inject, flags.injectFile);
|
|
3951
|
+
if (inject.length > 0 && flags.denyEgress) {
|
|
3952
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--inject cannot be combined with --deny-egress." });
|
|
3953
|
+
}
|
|
3954
|
+
if (flags.clearInject && (inject.length > 0 || flags.denyEgress)) {
|
|
3955
|
+
return yield* new InvalidMicroVmOptionsError({
|
|
3956
|
+
message: "--clear-inject cannot be combined with --inject or --deny-egress."
|
|
3957
|
+
});
|
|
3958
|
+
}
|
|
3901
3959
|
const apiClient = yield* ApiClientService;
|
|
3902
3960
|
const vm = yield* apiClient.request(
|
|
3903
3961
|
(client) => client.microvms.updateNetwork(
|
|
3904
3962
|
microvmId,
|
|
3905
|
-
flags.denyEgress ? { egress: "deny" } :
|
|
3963
|
+
flags.denyEgress ? { egress: "deny" } : {
|
|
3964
|
+
egress: "allow",
|
|
3965
|
+
...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {},
|
|
3966
|
+
...inject.length > 0 || flags.clearInject ? { inject } : {}
|
|
3967
|
+
}
|
|
3906
3968
|
)
|
|
3907
3969
|
);
|
|
3908
3970
|
const reach = vm.network.egress === "deny" ? "no outbound traffic" : vm.network.allow ? vm.network.allow.join(", ") : "the whole internet";
|
|
3909
3971
|
yield* import_effect24.Console.log(`${vm.id} now reaches ${reach}.`);
|
|
3972
|
+
for (const rule of vm.network.inject ?? []) {
|
|
3973
|
+
yield* import_effect24.Console.log(`Adds ${rule.headers.join(", ")} to HTTPS requests to ${rule.domain}.`);
|
|
3974
|
+
}
|
|
3910
3975
|
return vm;
|
|
3911
3976
|
});
|
|
3912
3977
|
var networkCommand = import_cli12.Command.make(
|
|
@@ -3922,6 +3987,21 @@ var networkCommand = import_cli12.Command.make(
|
|
|
3922
3987
|
),
|
|
3923
3988
|
allowAllEgress: import_cli12.Options.boolean("allow-all-egress").pipe(
|
|
3924
3989
|
import_cli12.Options.withDescription("Reach the whole internet again (private networks stay blocked)")
|
|
3990
|
+
),
|
|
3991
|
+
inject: import_cli12.Options.text("inject").pipe(
|
|
3992
|
+
import_cli12.Options.withDescription(
|
|
3993
|
+
"Add a header to HTTPS requests to a domain, as DOMAIN:HEADER=VALUE (repeatable, up to 8 domains); the value never enters the microVM"
|
|
3994
|
+
),
|
|
3995
|
+
import_cli12.Options.repeated
|
|
3996
|
+
),
|
|
3997
|
+
injectFile: import_cli12.Options.text("inject-file").pipe(
|
|
3998
|
+
import_cli12.Options.withDescription(
|
|
3999
|
+
"Read --inject rules from a file, one DOMAIN:HEADER=VALUE per line (/dev/stdin for a pipe), so the values stay out of the command line"
|
|
4000
|
+
),
|
|
4001
|
+
import_cli12.Options.optional
|
|
4002
|
+
),
|
|
4003
|
+
clearInject: import_cli12.Options.boolean("clear-inject").pipe(
|
|
4004
|
+
import_cli12.Options.withDescription("Remove every header rule added with --inject")
|
|
3925
4005
|
)
|
|
3926
4006
|
},
|
|
3927
4007
|
({ microvmId, ...flags }) => updateMicroVmNetwork(microvmId, flags).pipe(import_effect24.Effect.asVoid, reportErrors2("update the microVM network"))
|