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.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { Effect as Effect29, Layer, LogLevel, Logger } from "effect";
|
|
|
9
9
|
// package.json
|
|
10
10
|
var package_default = {
|
|
11
11
|
name: "gigadrive",
|
|
12
|
-
version: "2.
|
|
12
|
+
version: "2.17.0",
|
|
13
13
|
repository: {
|
|
14
14
|
type: "git",
|
|
15
15
|
url: "https://github.com/Gigadrive/sdk.git",
|
|
@@ -3063,6 +3063,7 @@ var describeMicroVm = (vm, now = Date.now()) => {
|
|
|
3063
3063
|
`Size: ${vm.vcpus} vCPU, ${formatMemory(vm.memoryMb)} memory, ${formatMemory(vm.diskMb)} disk`,
|
|
3064
3064
|
`Region: ${vm.region}`,
|
|
3065
3065
|
`Network: ${vm.network.egress === "deny" ? "outbound traffic blocked" : vm.network.allow && vm.network.allow.length > 0 ? `only ${vm.network.allow.join(", ")}` : "internet access"}`,
|
|
3066
|
+
...(vm.network.inject ?? []).map((rule) => `Injects: ${rule.headers.join(", ")} for ${rule.domain}`),
|
|
3066
3067
|
`Previews: ${vm.network.previews === "private" ? "private (preview token required)" : "public"}`,
|
|
3067
3068
|
`Application: ${vm.applicationId}`,
|
|
3068
3069
|
`Created: ${vm.createdAt}`
|
|
@@ -3373,6 +3374,37 @@ var parseVolumeFlags = (values) => Effect22.gen(function* () {
|
|
|
3373
3374
|
}
|
|
3374
3375
|
return volumes;
|
|
3375
3376
|
});
|
|
3377
|
+
var parseInjectFlags = (values) => Effect22.gen(function* () {
|
|
3378
|
+
const rules = /* @__PURE__ */ new Map();
|
|
3379
|
+
for (const value of values) {
|
|
3380
|
+
const colon = value.indexOf(":");
|
|
3381
|
+
const equals = value.indexOf("=", colon + 1);
|
|
3382
|
+
const domain = colon > 0 ? value.slice(0, colon).trim().toLowerCase() : "";
|
|
3383
|
+
const name = colon > 0 && equals > colon ? value.slice(colon + 1, equals).trim() : "";
|
|
3384
|
+
if (domain === "" || name === "" || equals === value.length - 1) {
|
|
3385
|
+
return yield* new InvalidMicroVmOptionsError({
|
|
3386
|
+
// The entry is not echoed: it may hold the credential.
|
|
3387
|
+
message: '--inject and --inject-file take DOMAIN:HEADER=VALUE, such as "api.openai.com:Authorization=Bearer $OPENAI_API_KEY".'
|
|
3388
|
+
});
|
|
3389
|
+
}
|
|
3390
|
+
rules.set(domain, { ...rules.get(domain), [name]: value.slice(equals + 1) });
|
|
3391
|
+
}
|
|
3392
|
+
if (rules.size > 8) {
|
|
3393
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--inject takes at most 8 domains." });
|
|
3394
|
+
}
|
|
3395
|
+
return [...rules].map(([domain, headers]) => ({ domain, headers }));
|
|
3396
|
+
});
|
|
3397
|
+
var readInjectRules = (inject, injectFile) => Effect22.gen(function* () {
|
|
3398
|
+
if (Option14.isNone(injectFile)) return yield* parseInjectFlags(inject);
|
|
3399
|
+
const fs = yield* FileSystem8.FileSystem;
|
|
3400
|
+
const content = yield* fs.readFileString(injectFile.value).pipe(
|
|
3401
|
+
Effect22.mapError(
|
|
3402
|
+
() => new InvalidMicroVmOptionsError({ message: `Could not read --inject-file ${injectFile.value}.` })
|
|
3403
|
+
)
|
|
3404
|
+
);
|
|
3405
|
+
const lines = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#"));
|
|
3406
|
+
return yield* parseInjectFlags([...inject, ...lines]);
|
|
3407
|
+
});
|
|
3376
3408
|
var checkEgressFlags = (denyEgress, allowEgress) => Effect22.gen(function* () {
|
|
3377
3409
|
if (denyEgress && allowEgress.length > 0) {
|
|
3378
3410
|
return yield* new InvalidMicroVmOptionsError({
|
|
@@ -3403,6 +3435,10 @@ var createInput = (flags) => Effect22.gen(function* () {
|
|
|
3403
3435
|
if (badPort !== void 0) {
|
|
3404
3436
|
return yield* new InvalidMicroVmOptionsError({ message: `--port must be between 1 and 65535 (got ${badPort}).` });
|
|
3405
3437
|
}
|
|
3438
|
+
const inject = yield* readInjectRules(flags.inject, flags.injectFile);
|
|
3439
|
+
if (inject.length > 0 && flags.denyEgress) {
|
|
3440
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--inject cannot be combined with --deny-egress." });
|
|
3441
|
+
}
|
|
3406
3442
|
const volumes = yield* parseVolumeFlags(flags.volumes);
|
|
3407
3443
|
if (volumes.length > 0 && flags.pauseOnTimeout) {
|
|
3408
3444
|
return yield* new InvalidMicroVmOptionsError({ message: "--volume cannot be combined with --pause-on-timeout." });
|
|
@@ -3424,11 +3460,12 @@ var createInput = (flags) => Effect22.gen(function* () {
|
|
|
3424
3460
|
...env ? { env } : {},
|
|
3425
3461
|
...metadata ? { metadata } : {},
|
|
3426
3462
|
...volumes.length > 0 ? { volumes } : {},
|
|
3427
|
-
...flags.denyEgress || flags.privatePreviews || flags.allowEgress.length > 0 ? {
|
|
3463
|
+
...flags.denyEgress || flags.privatePreviews || flags.allowEgress.length > 0 || inject.length > 0 ? {
|
|
3428
3464
|
network: {
|
|
3429
3465
|
egress: flags.denyEgress ? "deny" : "allow",
|
|
3430
3466
|
...flags.privatePreviews ? { previews: "private" } : {},
|
|
3431
|
-
...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {}
|
|
3467
|
+
...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {},
|
|
3468
|
+
...inject.length > 0 ? { inject } : {}
|
|
3432
3469
|
}
|
|
3433
3470
|
} : {},
|
|
3434
3471
|
...Option14.match(flags.region, { onNone: () => ({}), onSome: (region) => ({ region }) })
|
|
@@ -3519,6 +3556,18 @@ var createCommand = Command12.make(
|
|
|
3519
3556
|
),
|
|
3520
3557
|
Options7.repeated
|
|
3521
3558
|
),
|
|
3559
|
+
inject: Options7.text("inject").pipe(
|
|
3560
|
+
Options7.withDescription(
|
|
3561
|
+
"Add a header to HTTPS requests to a domain, as DOMAIN:HEADER=VALUE (repeatable, up to 8 domains); the value never enters the microVM"
|
|
3562
|
+
),
|
|
3563
|
+
Options7.repeated
|
|
3564
|
+
),
|
|
3565
|
+
injectFile: Options7.text("inject-file").pipe(
|
|
3566
|
+
Options7.withDescription(
|
|
3567
|
+
"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"
|
|
3568
|
+
),
|
|
3569
|
+
Options7.optional
|
|
3570
|
+
),
|
|
3522
3571
|
pauseOnTimeout: Options7.boolean("pause-on-timeout").pipe(
|
|
3523
3572
|
Options7.withDescription("Pause the microVM when its timeout ends instead of stopping it")
|
|
3524
3573
|
),
|
|
@@ -3888,15 +3937,31 @@ var updateMicroVmNetwork = (microvmId, flags) => Effect22.gen(function* () {
|
|
|
3888
3937
|
});
|
|
3889
3938
|
}
|
|
3890
3939
|
yield* checkEgressFlags(flags.denyEgress, flags.allowEgress);
|
|
3940
|
+
const inject = yield* readInjectRules(flags.inject, flags.injectFile);
|
|
3941
|
+
if (inject.length > 0 && flags.denyEgress) {
|
|
3942
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--inject cannot be combined with --deny-egress." });
|
|
3943
|
+
}
|
|
3944
|
+
if (flags.clearInject && (inject.length > 0 || flags.denyEgress)) {
|
|
3945
|
+
return yield* new InvalidMicroVmOptionsError({
|
|
3946
|
+
message: "--clear-inject cannot be combined with --inject or --deny-egress."
|
|
3947
|
+
});
|
|
3948
|
+
}
|
|
3891
3949
|
const apiClient = yield* ApiClientService;
|
|
3892
3950
|
const vm = yield* apiClient.request(
|
|
3893
3951
|
(client) => client.microvms.updateNetwork(
|
|
3894
3952
|
microvmId,
|
|
3895
|
-
flags.denyEgress ? { egress: "deny" } :
|
|
3953
|
+
flags.denyEgress ? { egress: "deny" } : {
|
|
3954
|
+
egress: "allow",
|
|
3955
|
+
...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {},
|
|
3956
|
+
...inject.length > 0 || flags.clearInject ? { inject } : {}
|
|
3957
|
+
}
|
|
3896
3958
|
)
|
|
3897
3959
|
);
|
|
3898
3960
|
const reach = vm.network.egress === "deny" ? "no outbound traffic" : vm.network.allow ? vm.network.allow.join(", ") : "the whole internet";
|
|
3899
3961
|
yield* Console12.log(`${vm.id} now reaches ${reach}.`);
|
|
3962
|
+
for (const rule of vm.network.inject ?? []) {
|
|
3963
|
+
yield* Console12.log(`Adds ${rule.headers.join(", ")} to HTTPS requests to ${rule.domain}.`);
|
|
3964
|
+
}
|
|
3900
3965
|
return vm;
|
|
3901
3966
|
});
|
|
3902
3967
|
var networkCommand = Command12.make(
|
|
@@ -3912,6 +3977,21 @@ var networkCommand = Command12.make(
|
|
|
3912
3977
|
),
|
|
3913
3978
|
allowAllEgress: Options7.boolean("allow-all-egress").pipe(
|
|
3914
3979
|
Options7.withDescription("Reach the whole internet again (private networks stay blocked)")
|
|
3980
|
+
),
|
|
3981
|
+
inject: Options7.text("inject").pipe(
|
|
3982
|
+
Options7.withDescription(
|
|
3983
|
+
"Add a header to HTTPS requests to a domain, as DOMAIN:HEADER=VALUE (repeatable, up to 8 domains); the value never enters the microVM"
|
|
3984
|
+
),
|
|
3985
|
+
Options7.repeated
|
|
3986
|
+
),
|
|
3987
|
+
injectFile: Options7.text("inject-file").pipe(
|
|
3988
|
+
Options7.withDescription(
|
|
3989
|
+
"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"
|
|
3990
|
+
),
|
|
3991
|
+
Options7.optional
|
|
3992
|
+
),
|
|
3993
|
+
clearInject: Options7.boolean("clear-inject").pipe(
|
|
3994
|
+
Options7.withDescription("Remove every header rule added with --inject")
|
|
3915
3995
|
)
|
|
3916
3996
|
},
|
|
3917
3997
|
({ microvmId, ...flags }) => updateMicroVmNetwork(microvmId, flags).pipe(Effect22.asVoid, reportErrors2("update the microVM network"))
|