@clawops/cli 1.4.0 → 1.6.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 +40 -0
- package/dist/{apply-5RREMN3L.js → apply-SI3JKS4Z.js} +2 -2
- package/dist/automation-RULUSJBW.js +0 -0
- package/dist/{aws-FRE2JVAZ.js → aws-D7Y6LCGK.js} +52 -90
- package/dist/{azure-PVC3AQVC.js → azure-JQAMNVHN.js} +15 -56
- package/dist/{bootstrap-G4UZ2FKH.js → bootstrap-RY4VOSDJ.js} +2 -2
- package/dist/chunk-3QJBNAHW.js +0 -0
- package/dist/chunk-6ZFIFDBJ.js +0 -0
- package/dist/{chunk-UAA6YOOP.js → chunk-72FF7IK2.js} +2 -2
- package/dist/chunk-A2I76FTA.js +0 -0
- package/dist/chunk-BOPSG2LI.js +0 -0
- package/dist/{chunk-JYQZJMD3.js → chunk-C5NDLOK2.js} +41 -33
- package/dist/chunk-CX5SL5HP.js +0 -0
- package/dist/{chunk-4U3LTLWZ.js → chunk-GJEF6UQA.js} +1 -0
- package/dist/chunk-KGXPLI7W.js +0 -0
- package/dist/{chunk-ZVOEQCNW.js → chunk-LCKD7L7X.js} +1 -1
- package/dist/chunk-OIGTOLB3.js +0 -0
- package/dist/{chunk-ZONXY3C6.js → chunk-QHGFENYR.js} +2 -2
- package/dist/{chunk-T5EX55GP.js → chunk-QI75OVJK.js} +3 -3
- package/dist/chunk-XKT42M34.js +72 -0
- package/dist/chunk-YTH4L2GN.js +0 -0
- package/dist/chunk-ZFNPM2WG.js +0 -0
- package/dist/cli.js +311 -54
- package/dist/{context-PSGEX2D7.js → context-KPKBOWOP.js} +1 -1
- package/dist/errors-OK47MQFD.js +0 -0
- package/dist/firewall-XQGO7HWK.js +51 -0
- package/dist/{gcp-BXDTC6EK.js → gcp-6FT2A45S.js} +14 -63
- package/dist/{generate-Z7DBMANX.js → generate-YV7226Q7.js} +2 -2
- package/dist/js-yaml-PTEEG4FO.js +0 -0
- package/dist/local-DXBEVZ5C.js +0 -0
- package/dist/mcp-apps-KY44ED3Y.js +0 -0
- package/dist/mcp-wire-ZWIYMLEW.js +45 -0
- package/dist/outputs-DJHBY7EE.js +0 -0
- package/dist/overlay-store-ADZPD7EU.js +0 -0
- package/dist/{package-WAJRGBBM.js → package-EW3FS257.js} +1 -1
- package/dist/{pool-FBFHATDG.js → pool-JZGKPP6K.js} +2 -2
- package/dist/providers-2OABPW2E.js +0 -0
- package/dist/remote-config-QF5TT7GU.js +0 -0
- package/dist/secrets-SVZWNAPK.js +0 -0
- package/dist/{server-IWLZJ4EU.js → server-3DEZHUWB.js} +9 -9
- package/dist/{ssh-IQXNME3D.js → ssh-E2AMBPZY.js} +1 -1
- package/dist/state-PRBIIN7I.js +0 -0
- package/dist/store-SDUR52Z5.js +0 -0
- package/dist/validate-T5M5EHSJ.js +0 -0
- package/package.json +26 -14
- package/dist/firewall-YYDOWDDP.js +0 -36
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/providers/firewall.ts
|
|
4
|
+
function resolveIngressCidrs(accessMode, allowedCidrs, portOverride, egressResult) {
|
|
5
|
+
if (portOverride.trim()) {
|
|
6
|
+
return portOverride.split(",").map((s) => s.trim()).filter(Boolean);
|
|
7
|
+
}
|
|
8
|
+
switch (accessMode) {
|
|
9
|
+
case "restricted": {
|
|
10
|
+
if (!allowedCidrs.trim()) return [];
|
|
11
|
+
return allowedCidrs.split(",").map((s) => s.trim()).filter(Boolean);
|
|
12
|
+
}
|
|
13
|
+
case "auto": {
|
|
14
|
+
if (!egressResult.ok) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`accessMode=auto: egress IP detection failed \u2014 ${egressResult.error}. Set allowedCidrs explicitly or use accessMode=restricted.`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const ip = egressResult.ip.trim();
|
|
20
|
+
if (!ip) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`accessMode=auto: egress IP detection returned an empty address. Set allowedCidrs explicitly or use accessMode=restricted.`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return [ip.includes("/") ? ip : `${ip}/32`];
|
|
26
|
+
}
|
|
27
|
+
case "open":
|
|
28
|
+
return ["0.0.0.0/0"];
|
|
29
|
+
default:
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function detectEgressIp(checkUrl) {
|
|
34
|
+
try {
|
|
35
|
+
const res = await fetch(checkUrl, { signal: AbortSignal.timeout(3e3) });
|
|
36
|
+
if (!res.ok) {
|
|
37
|
+
return { ok: false, error: `HTTP ${res.status} from ${checkUrl}` };
|
|
38
|
+
}
|
|
39
|
+
const ip = (await res.text()).trim();
|
|
40
|
+
if (!ip) {
|
|
41
|
+
return { ok: false, error: `empty response from ${checkUrl}` };
|
|
42
|
+
}
|
|
43
|
+
return { ok: true, ip };
|
|
44
|
+
} catch (err) {
|
|
45
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
detectEgressIp,
|
|
50
|
+
resolveIngressCidrs
|
|
51
|
+
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
makeStartupScript
|
|
4
|
+
} from "./chunk-XKT42M34.js";
|
|
2
5
|
|
|
3
6
|
// src/providers/gcp/index.ts
|
|
4
7
|
import process2 from "process";
|
|
@@ -10,7 +13,7 @@ var gcpProgram = async () => {
|
|
|
10
13
|
const [pulumi, gcp, { resolveIngressCidrs, detectEgressIp }] = await Promise.all([
|
|
11
14
|
import("@pulumi/pulumi"),
|
|
12
15
|
import("@pulumi/gcp"),
|
|
13
|
-
import("./firewall-
|
|
16
|
+
import("./firewall-XQGO7HWK.js")
|
|
14
17
|
]);
|
|
15
18
|
const cfg = new pulumi.Config();
|
|
16
19
|
const instanceType = cfg.get("instanceType") ?? "e2-standard-2";
|
|
@@ -27,14 +30,14 @@ var gcpProgram = async () => {
|
|
|
27
30
|
'Stack config "sshPublicKey" is required for the GCP adapter. Set it with: pulumi config set --stack <name> sshPublicKey "ssh-ed25519 ..."'
|
|
28
31
|
);
|
|
29
32
|
}
|
|
30
|
-
const
|
|
33
|
+
const egressResult = accessMode === "auto" ? await detectEgressIp("https://ifconfig.me") : { ok: true, ip: "" };
|
|
31
34
|
if (accessMode === "open") {
|
|
32
35
|
process.stderr.write(
|
|
33
36
|
"[clawops] WARNING: accessMode=open allows 0.0.0.0/0 on SSH and gateway ports. Only use this for development/sandbox stacks.\n"
|
|
34
37
|
);
|
|
35
38
|
}
|
|
36
|
-
const sshIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, sshCidrs,
|
|
37
|
-
const gatewayIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, gatewayCidrs,
|
|
39
|
+
const sshIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, sshCidrs, egressResult);
|
|
40
|
+
const gatewayIngressCidrs = resolveIngressCidrs(accessMode, allowedCidrs, gatewayCidrs, egressResult);
|
|
38
41
|
const network = new gcp.compute.Network("clawops-network", {
|
|
39
42
|
autoCreateSubnetworks: false,
|
|
40
43
|
description: "clawops managed network"
|
|
@@ -42,7 +45,7 @@ var gcpProgram = async () => {
|
|
|
42
45
|
const subnet = new gcp.compute.Subnetwork("clawops-subnet", {
|
|
43
46
|
ipCidrRange: "10.0.0.0/24",
|
|
44
47
|
region,
|
|
45
|
-
network: network.
|
|
48
|
+
network: network.selfLink
|
|
46
49
|
});
|
|
47
50
|
if (sshIngressCidrs.length > 0) {
|
|
48
51
|
new gcp.compute.Firewall("clawops-firewall-ssh", {
|
|
@@ -73,8 +76,8 @@ var gcpProgram = async () => {
|
|
|
73
76
|
},
|
|
74
77
|
networkInterfaces: [
|
|
75
78
|
{
|
|
76
|
-
network: network.
|
|
77
|
-
subnetwork: subnet.
|
|
79
|
+
network: network.selfLink,
|
|
80
|
+
subnetwork: subnet.selfLink,
|
|
78
81
|
accessConfigs: [
|
|
79
82
|
{
|
|
80
83
|
natIp: address.address,
|
|
@@ -86,7 +89,7 @@ var gcpProgram = async () => {
|
|
|
86
89
|
metadata: {
|
|
87
90
|
// GCP guest agent reads 'ssh-keys' and populates /home/<user>/.ssh/authorized_keys
|
|
88
91
|
"ssh-keys": `clawops:${sshPublicKey}`,
|
|
89
|
-
"startup-script": makeStartupScript(openclawVersion)
|
|
92
|
+
"startup-script": makeStartupScript({ openclawVersion, os: "debian" })
|
|
90
93
|
},
|
|
91
94
|
serviceAccount: {
|
|
92
95
|
scopes: ["https://www.googleapis.com/auth/cloud-platform"]
|
|
@@ -103,58 +106,6 @@ var gcpProgram = async () => {
|
|
|
103
106
|
provisionedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
104
107
|
};
|
|
105
108
|
};
|
|
106
|
-
function makeStartupScript(openclawVersion) {
|
|
107
|
-
return `#!/bin/bash
|
|
108
|
-
set -euo pipefail
|
|
109
|
-
|
|
110
|
-
# Create clawops user with SSH access
|
|
111
|
-
id -u clawops &>/dev/null || useradd -m -s /bin/bash clawops
|
|
112
|
-
mkdir -p /home/clawops/.ssh
|
|
113
|
-
chmod 700 /home/clawops/.ssh
|
|
114
|
-
|
|
115
|
-
# Install Docker if not present
|
|
116
|
-
if ! command -v docker &>/dev/null; then
|
|
117
|
-
apt-get update -q
|
|
118
|
-
apt-get install -y -q ca-certificates curl gnupg lsb-release
|
|
119
|
-
install -m 0755 -d /etc/apt/keyrings
|
|
120
|
-
curl -fsSL https://download.docker.com/linux/debian/gpg \\
|
|
121
|
-
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
|
122
|
-
chmod a+r /etc/apt/keyrings/docker.gpg
|
|
123
|
-
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \\
|
|
124
|
-
https://download.docker.com/linux/debian $(lsb_release -cs) stable" \\
|
|
125
|
-
> /etc/apt/sources.list.d/docker.list
|
|
126
|
-
apt-get update -q
|
|
127
|
-
apt-get install -y -q docker-ce docker-ce-cli containerd.io
|
|
128
|
-
systemctl enable --now docker
|
|
129
|
-
fi
|
|
130
|
-
|
|
131
|
-
usermod -aG docker clawops
|
|
132
|
-
|
|
133
|
-
# Pull OpenClaw image
|
|
134
|
-
OPENCLAW_VERSION="${openclawVersion}"
|
|
135
|
-
docker pull ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION}
|
|
136
|
-
|
|
137
|
-
# Create default openclaw.json if not present
|
|
138
|
-
OPENCLAW_CONFIG=/home/clawops/openclaw.json
|
|
139
|
-
if [ ! -f "\${OPENCLAW_CONFIG}" ]; then
|
|
140
|
-
cat > "\${OPENCLAW_CONFIG}" <<'OPENCLAWJSON'
|
|
141
|
-
{"meta":{"lastTouchedVersion":"2026.4"},"gateway":{"port":18789,"auth":{"mode":"token"}},"models":{},"channels":{}}
|
|
142
|
-
OPENCLAWJSON
|
|
143
|
-
chown clawops:clawops "\${OPENCLAW_CONFIG}"
|
|
144
|
-
fi
|
|
145
|
-
|
|
146
|
-
# Start OpenClaw container
|
|
147
|
-
docker stop openclaw 2>/dev/null || true
|
|
148
|
-
docker rm openclaw 2>/dev/null || true
|
|
149
|
-
docker run -d \\
|
|
150
|
-
--name openclaw \\
|
|
151
|
-
--restart unless-stopped \\
|
|
152
|
-
-p ${GATEWAY_PORT}:${GATEWAY_PORT} \\
|
|
153
|
-
-v "\${OPENCLAW_CONFIG}":/app/config.json:ro \\
|
|
154
|
-
ghcr.io/openclaw/openclaw:\${OPENCLAW_VERSION} \\
|
|
155
|
-
node openclaw.mjs gateway run --allow-unconfigured
|
|
156
|
-
`;
|
|
157
|
-
}
|
|
158
109
|
|
|
159
110
|
// src/providers/gcp/index.ts
|
|
160
111
|
var INSTANCE_TYPE_MAP = {
|
|
@@ -172,9 +123,9 @@ var gcpAdapter = {
|
|
|
172
123
|
},
|
|
173
124
|
getConnectionInfo(outputs) {
|
|
174
125
|
return {
|
|
175
|
-
host: String(outputs["sshHost"]),
|
|
176
|
-
port: Number(outputs["sshPort"]),
|
|
177
|
-
user: String(outputs["sshUser"]),
|
|
126
|
+
host: String(outputs["sshHost"] ?? ""),
|
|
127
|
+
port: Number(outputs["sshPort"] ?? 22),
|
|
128
|
+
user: String(outputs["sshUser"] ?? "clawops"),
|
|
178
129
|
privateKeyPath: String(outputs["privateKeyPath"] ?? ""),
|
|
179
130
|
knownHostsPath: String(outputs["knownHostsPath"] ?? "")
|
|
180
131
|
};
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
generatePlan,
|
|
4
4
|
planId
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-72FF7IK2.js";
|
|
6
6
|
import "./chunk-YTH4L2GN.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-QI75OVJK.js";
|
|
8
8
|
import "./chunk-A2I76FTA.js";
|
|
9
9
|
import "./chunk-CX5SL5HP.js";
|
|
10
10
|
import "./chunk-KGXPLI7W.js";
|
package/dist/js-yaml-PTEEG4FO.js
CHANGED
|
File without changes
|
package/dist/local-DXBEVZ5C.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
atomicWriteConfig,
|
|
4
|
+
deepMerge,
|
|
5
|
+
readRemoteConfig,
|
|
6
|
+
restartGateway
|
|
7
|
+
} from "./chunk-ZFNPM2WG.js";
|
|
8
|
+
|
|
9
|
+
// src/cli/mcp-wire.ts
|
|
10
|
+
var GATEWAY_MCP_MIN_VERSION = "2026.4";
|
|
11
|
+
var GATEWAY_MCP_ENTRY = {
|
|
12
|
+
command: "clawops",
|
|
13
|
+
args: ["mcp", "serve"],
|
|
14
|
+
transport: "stdio"
|
|
15
|
+
};
|
|
16
|
+
function versionAtLeast(version, min) {
|
|
17
|
+
const [vy = 0, vm = 0] = version.split(".").map(Number);
|
|
18
|
+
const [my = 0, mm = 0] = min.split(".").map(Number);
|
|
19
|
+
if (vy !== my) return vy > my;
|
|
20
|
+
return vm >= mm;
|
|
21
|
+
}
|
|
22
|
+
async function wireGatewayMcp(session, signal, opts = {}) {
|
|
23
|
+
const cfg = await readRemoteConfig(session, signal);
|
|
24
|
+
const version = cfg["meta"]?.["lastTouchedVersion"];
|
|
25
|
+
if (version && !versionAtLeast(version, GATEWAY_MCP_MIN_VERSION) && !opts.force) {
|
|
26
|
+
return { status: "version-blocked", version };
|
|
27
|
+
}
|
|
28
|
+
const mcpClients = cfg["gateway"]?.["mcpClients"];
|
|
29
|
+
const rewired = !!mcpClients?.["clawops"];
|
|
30
|
+
const updated = deepMerge(cfg, {
|
|
31
|
+
gateway: {
|
|
32
|
+
mcpClients: {
|
|
33
|
+
clawops: GATEWAY_MCP_ENTRY
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
await atomicWriteConfig(session, updated, signal);
|
|
38
|
+
await restartGateway(session, signal);
|
|
39
|
+
return { status: "wired", rewired };
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
GATEWAY_MCP_ENTRY,
|
|
43
|
+
GATEWAY_MCP_MIN_VERSION,
|
|
44
|
+
wireGatewayMcp
|
|
45
|
+
};
|
package/dist/outputs-DJHBY7EE.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/secrets-SVZWNAPK.js
CHANGED
|
File without changes
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-3QJBNAHW.js";
|
|
5
5
|
import {
|
|
6
6
|
generatePlan
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-72FF7IK2.js";
|
|
8
8
|
import {
|
|
9
9
|
applyPlan
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QHGFENYR.js";
|
|
11
11
|
import {
|
|
12
12
|
validatePlan
|
|
13
13
|
} from "./chunk-YTH4L2GN.js";
|
|
@@ -23,15 +23,15 @@ import {
|
|
|
23
23
|
handleConfigValidate,
|
|
24
24
|
okText,
|
|
25
25
|
resolveConn
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-C5NDLOK2.js";
|
|
27
27
|
import {
|
|
28
28
|
buildContext
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-QI75OVJK.js";
|
|
30
30
|
import {
|
|
31
31
|
acquireSession,
|
|
32
32
|
drainPool
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import "./chunk-
|
|
33
|
+
} from "./chunk-LCKD7L7X.js";
|
|
34
|
+
import "./chunk-GJEF6UQA.js";
|
|
35
35
|
import "./chunk-ZFNPM2WG.js";
|
|
36
36
|
import "./chunk-A2I76FTA.js";
|
|
37
37
|
import {
|
|
@@ -630,7 +630,7 @@ async function handleUp(input, server) {
|
|
|
630
630
|
);
|
|
631
631
|
}
|
|
632
632
|
const { localOpts } = stackConfig;
|
|
633
|
-
const { localBootstrap } = await import("./bootstrap-
|
|
633
|
+
const { localBootstrap } = await import("./bootstrap-RY4VOSDJ.js");
|
|
634
634
|
const ac = new AbortController();
|
|
635
635
|
const state = await localBootstrap({
|
|
636
636
|
host: localOpts.host,
|
|
@@ -853,7 +853,7 @@ async function handleTaskStatus(input, _server) {
|
|
|
853
853
|
|
|
854
854
|
// src/mcp/tools/cli/monitor.ts
|
|
855
855
|
async function handleMonitor(input, _server) {
|
|
856
|
-
const { acquireSession: acquireSession2, drainPool: drainPool2 } = await import("./pool-
|
|
856
|
+
const { acquireSession: acquireSession2, drainPool: drainPool2 } = await import("./pool-JZGKPP6K.js");
|
|
857
857
|
const ctx = buildContext({ stack: input.stackName });
|
|
858
858
|
const tailLines = input.tailLines ?? 5;
|
|
859
859
|
let conn;
|
|
@@ -1305,7 +1305,7 @@ If none of the above resolves the issue:
|
|
|
1305
1305
|
|
|
1306
1306
|
// src/mcp/server.ts
|
|
1307
1307
|
async function serveMcp(opts) {
|
|
1308
|
-
const { version } = await import("./package-
|
|
1308
|
+
const { version } = await import("./package-EW3FS257.js");
|
|
1309
1309
|
const server = new McpServer({ name: "clawops", version });
|
|
1310
1310
|
registerTools(server, opts);
|
|
1311
1311
|
registerResources(server);
|
package/dist/state-PRBIIN7I.js
CHANGED
|
File without changes
|
package/dist/store-SDUR52Z5.js
CHANGED
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clawops/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Deploy and manage self-hosted OpenClaw instances across clouds",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,6 +24,19 @@
|
|
|
24
24
|
"engines": {
|
|
25
25
|
"node": ">=22"
|
|
26
26
|
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"dev": "tsx src/cli/index.ts",
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:pulumi": "vitest run tests/providers/aws/program.test.ts tests/providers/azure/program.test.ts",
|
|
32
|
+
"test:changed": "vitest --changed",
|
|
33
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
34
|
+
"typecheck": "NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit",
|
|
35
|
+
"lint": "eslint --max-warnings=0 src tests scripts",
|
|
36
|
+
"gen:schemas": "tsx scripts/gen-schemas.ts",
|
|
37
|
+
"changeset": "changeset",
|
|
38
|
+
"release": "pnpm build && changeset publish"
|
|
39
|
+
},
|
|
27
40
|
"dependencies": {
|
|
28
41
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
29
42
|
"@pulumi/aws": "^6.0.0",
|
|
@@ -60,17 +73,16 @@
|
|
|
60
73
|
"typescript-eslint": "^8.0.0",
|
|
61
74
|
"vitest": "^2.0.0"
|
|
62
75
|
},
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"release": "pnpm build && changeset publish"
|
|
76
|
+
"pnpm": {
|
|
77
|
+
"overrides": {
|
|
78
|
+
"@pulumi/pulumi": "^3.0.0"
|
|
79
|
+
},
|
|
80
|
+
"onlyBuiltDependencies": [
|
|
81
|
+
"@pulumi/command",
|
|
82
|
+
"cpu-features",
|
|
83
|
+
"esbuild",
|
|
84
|
+
"protobufjs",
|
|
85
|
+
"ssh2"
|
|
86
|
+
]
|
|
75
87
|
}
|
|
76
|
-
}
|
|
88
|
+
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/providers/firewall.ts
|
|
4
|
-
function resolveIngressCidrs(accessMode, allowedCidrs, portOverride, detectedIp) {
|
|
5
|
-
if (portOverride.trim()) {
|
|
6
|
-
return portOverride.split(",").map((s) => s.trim()).filter(Boolean);
|
|
7
|
-
}
|
|
8
|
-
switch (accessMode) {
|
|
9
|
-
case "restricted": {
|
|
10
|
-
if (!allowedCidrs.trim()) return [];
|
|
11
|
-
return allowedCidrs.split(",").map((s) => s.trim()).filter(Boolean);
|
|
12
|
-
}
|
|
13
|
-
case "auto": {
|
|
14
|
-
if (!detectedIp.trim()) return [];
|
|
15
|
-
const ip = detectedIp.trim();
|
|
16
|
-
return [ip.includes("/") ? ip : `${ip}/32`];
|
|
17
|
-
}
|
|
18
|
-
case "open":
|
|
19
|
-
return ["0.0.0.0/0"];
|
|
20
|
-
default:
|
|
21
|
-
return [];
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
async function detectEgressIp(checkUrl) {
|
|
25
|
-
try {
|
|
26
|
-
const res = await fetch(checkUrl, { signal: AbortSignal.timeout(5e3) });
|
|
27
|
-
if (!res.ok) return "";
|
|
28
|
-
return (await res.text()).trim();
|
|
29
|
-
} catch {
|
|
30
|
-
return "";
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export {
|
|
34
|
-
detectEgressIp,
|
|
35
|
-
resolveIngressCidrs
|
|
36
|
-
};
|