@envsync-cloud/deploy-cli 0.8.15 → 0.8.16
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.js +118 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5181,6 +5181,30 @@ function validateStaticBundle(kind, targetDir) {
|
|
|
5181
5181
|
}
|
|
5182
5182
|
|
|
5183
5183
|
// src/index.ts
|
|
5184
|
+
var NETUTILS_EXPOSE_ALL_START_PORT = 15e3;
|
|
5185
|
+
var NETUTILS_EXPOSE_ALL_PORTS = [
|
|
5186
|
+
{ service: "postgres", service_port: 5432, protocol: "tcp" },
|
|
5187
|
+
{ service: "envsync_api_blue", service_port: 4e3, protocol: "tcp" },
|
|
5188
|
+
{ service: "envsync_api_green", service_port: 4e3, protocol: "tcp" },
|
|
5189
|
+
{ service: "envsync-management-api", service_port: 4001, protocol: "tcp" },
|
|
5190
|
+
{ service: "keycloak", service_port: 8080, protocol: "tcp" },
|
|
5191
|
+
{ service: "openfga", service_port: 8090, protocol: "tcp" },
|
|
5192
|
+
{ service: "minikms", service_port: 50051, protocol: "tcp" },
|
|
5193
|
+
{ service: "keycloak_db", service_port: 5432, protocol: "tcp" },
|
|
5194
|
+
{ service: "openfga_db", service_port: 5432, protocol: "tcp" },
|
|
5195
|
+
{ service: "minikms_db", service_port: 5432, protocol: "tcp" },
|
|
5196
|
+
{ service: "redis", service_port: 6379, protocol: "tcp" },
|
|
5197
|
+
{ service: "rustfs", service_port: 9e3, protocol: "tcp" },
|
|
5198
|
+
{ service: "rustfs", service_port: 9001, protocol: "tcp" },
|
|
5199
|
+
{ service: "clickstack", service_port: 8080, protocol: "tcp" },
|
|
5200
|
+
{ service: "otel-agent", service_port: 4317, protocol: "tcp" },
|
|
5201
|
+
{ service: "otel-agent", service_port: 4318, protocol: "tcp" },
|
|
5202
|
+
{ service: "traefik", service_port: 80, protocol: "tcp" },
|
|
5203
|
+
{ service: "traefik", service_port: 443, protocol: "tcp" },
|
|
5204
|
+
{ service: "web_nginx", service_port: 80, protocol: "tcp" },
|
|
5205
|
+
{ service: "landing_nginx", service_port: 80, protocol: "tcp" },
|
|
5206
|
+
{ service: "api_maintenance", service_port: 80, protocol: "tcp" }
|
|
5207
|
+
];
|
|
5184
5208
|
var HOST_ROOT = process.env.ENVSYNC_HOST_ROOT ?? "/opt/envsync";
|
|
5185
5209
|
var ETC_ROOT = process.env.ENVSYNC_ETC_ROOT ?? "/etc/envsync";
|
|
5186
5210
|
var TRAEFIK_STATE_ROOT = process.env.ENVSYNC_TRAEFIK_STATE_ROOT ?? "/var/lib/envsync/traefik";
|
|
@@ -5386,6 +5410,69 @@ ${stderr}` : ""}`);
|
|
|
5386
5410
|
}
|
|
5387
5411
|
return (result.stdout ?? "").toString().trim();
|
|
5388
5412
|
}
|
|
5413
|
+
function chunkByMax(items, max) {
|
|
5414
|
+
if (items.length === 0) return [];
|
|
5415
|
+
const chunks = [];
|
|
5416
|
+
for (let i = 0; i < items.length; i += max) {
|
|
5417
|
+
chunks.push(items.slice(i, i + max));
|
|
5418
|
+
}
|
|
5419
|
+
return chunks;
|
|
5420
|
+
}
|
|
5421
|
+
function formatPortRangesForIptables(ports) {
|
|
5422
|
+
const sortedPorts = Array.from(new Set(ports)).map((port) => parseInt(String(port), 10)).filter((port) => Number.isInteger(port) && port >= 1 && port <= 65535).sort((a, b) => a - b);
|
|
5423
|
+
if (sortedPorts.length === 0) return [];
|
|
5424
|
+
const ranges = [];
|
|
5425
|
+
let rangeStart = sortedPorts[0];
|
|
5426
|
+
let previous = sortedPorts[0];
|
|
5427
|
+
for (let i = 1; i < sortedPorts.length; i++) {
|
|
5428
|
+
const current = sortedPorts[i];
|
|
5429
|
+
if (current === previous + 1) {
|
|
5430
|
+
previous = current;
|
|
5431
|
+
continue;
|
|
5432
|
+
}
|
|
5433
|
+
ranges.push(rangeStart === previous ? `${rangeStart}` : `${rangeStart}:${previous}`);
|
|
5434
|
+
rangeStart = current;
|
|
5435
|
+
previous = current;
|
|
5436
|
+
}
|
|
5437
|
+
ranges.push(rangeStart === previous ? `${rangeStart}` : `${rangeStart}:${previous}`);
|
|
5438
|
+
return ranges;
|
|
5439
|
+
}
|
|
5440
|
+
function formatNetutilsFirewallRules(config) {
|
|
5441
|
+
if (!config?.netutils?.enabled || !Array.isArray(config.netutils.forwards) || config.netutils.forwards.length === 0) {
|
|
5442
|
+
return [];
|
|
5443
|
+
}
|
|
5444
|
+
const tcpPorts = config.netutils.forwards.filter((item) => item.protocol === "tcp").map((item) => item.host_port);
|
|
5445
|
+
const udpPorts = config.netutils.forwards.filter((item) => item.protocol === "udp").map((item) => item.host_port);
|
|
5446
|
+
const tcpRanges = formatPortRangesForIptables(tcpPorts);
|
|
5447
|
+
const udpRanges = formatPortRangesForIptables(udpPorts);
|
|
5448
|
+
if (tcpRanges.length === 0 && udpRanges.length === 0) return [];
|
|
5449
|
+
const lines = [];
|
|
5450
|
+
const addRules = (protocol, ranges) => {
|
|
5451
|
+
for (const chunk of chunkByMax(ranges, 15)) {
|
|
5452
|
+
const portSpec = chunk.join(",");
|
|
5453
|
+
lines.push(
|
|
5454
|
+
`PostUp = iptables -I DOCKER-USER -i envsync-wg -p ${protocol} -m multiport --dports ${portSpec} -j ACCEPT`
|
|
5455
|
+
);
|
|
5456
|
+
lines.push(`PostUp = iptables -A DOCKER-USER -p ${protocol} -m multiport --dports ${portSpec} -j DROP`);
|
|
5457
|
+
lines.push(
|
|
5458
|
+
`PostDown = iptables -D DOCKER-USER -p ${protocol} -m multiport --dports ${portSpec} -j DROP`
|
|
5459
|
+
);
|
|
5460
|
+
lines.push(
|
|
5461
|
+
`PostDown = iptables -D DOCKER-USER -i envsync-wg -p ${protocol} -m multiport --dports ${portSpec} -j ACCEPT`
|
|
5462
|
+
);
|
|
5463
|
+
}
|
|
5464
|
+
};
|
|
5465
|
+
addRules("tcp", tcpRanges);
|
|
5466
|
+
addRules("udp", udpRanges);
|
|
5467
|
+
return lines;
|
|
5468
|
+
}
|
|
5469
|
+
function tryLoadOptionalConfig() {
|
|
5470
|
+
try {
|
|
5471
|
+
return loadConfig();
|
|
5472
|
+
} catch {
|
|
5473
|
+
return null;
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5389
5476
|
function parseJsonOrDefault(value, fallback) {
|
|
5390
5477
|
try {
|
|
5391
5478
|
return JSON.parse(value);
|
|
@@ -5510,6 +5597,15 @@ function parseNetutilsForwardsFromInput(raw, stackName) {
|
|
|
5510
5597
|
});
|
|
5511
5598
|
return normalizeNetutilsForwards(candidates, stackName, true).forwards;
|
|
5512
5599
|
}
|
|
5600
|
+
function buildNetutilsExposeAllForwards(stackName) {
|
|
5601
|
+
const candidates = NETUTILS_EXPOSE_ALL_PORTS.map((forward, index) => ({
|
|
5602
|
+
service: forward.service,
|
|
5603
|
+
service_port: forward.service_port,
|
|
5604
|
+
host_port: NETUTILS_EXPOSE_ALL_START_PORT + index,
|
|
5605
|
+
protocol: forward.protocol
|
|
5606
|
+
}));
|
|
5607
|
+
return normalizeNetutilsForwards(candidates, stackName, true).forwards;
|
|
5608
|
+
}
|
|
5513
5609
|
function normalizeNetutilsProtocol(raw) {
|
|
5514
5610
|
if (typeof raw === "string") {
|
|
5515
5611
|
const protocol = raw.toLowerCase();
|
|
@@ -5635,6 +5731,8 @@ function wireguardPeerAllowedIp(state) {
|
|
|
5635
5731
|
throw new Error("WireGuard client IP pool exhausted in subnet 10.66.0.0/24.");
|
|
5636
5732
|
}
|
|
5637
5733
|
function writeWireguardConfig(state) {
|
|
5734
|
+
const config = tryLoadOptionalConfig();
|
|
5735
|
+
const netutilsFirewallRules = formatNetutilsFirewallRules(config);
|
|
5638
5736
|
const peersSection = state.peers.map((peer) => `
|
|
5639
5737
|
[Peer]
|
|
5640
5738
|
PublicKey = ${peer.public_key}
|
|
@@ -5647,6 +5745,7 @@ PostUp = iptables -A FORWARD -i envsync-wg -j ACCEPT
|
|
|
5647
5745
|
PostDown = iptables -D FORWARD -i envsync-wg -j ACCEPT
|
|
5648
5746
|
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
|
5649
5747
|
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
|
5748
|
+
${netutilsFirewallRules.join("\n")}
|
|
5650
5749
|
${peersSection}
|
|
5651
5750
|
`;
|
|
5652
5751
|
writeFileMaybe(WIREGUARD_CONFIG_FILE, content);
|
|
@@ -7466,13 +7565,25 @@ async function cmdSetup() {
|
|
|
7466
7565
|
const publicObs = await ask("Expose obs.<domain> publicly (true/false)", "true") === "true";
|
|
7467
7566
|
const mailpitEnabled = await ask("Enable mailpit (true/false)", "false") === "true";
|
|
7468
7567
|
const netutilsEnabled = await ask("Enable WireGuard jump host access (true/false)", "false") === "true";
|
|
7469
|
-
const
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7568
|
+
const netutilsExposeAll = netutilsEnabled ? await ask("Expose all EnvSync service ports over WireGuard (true/false)", "false") === "true" : false;
|
|
7569
|
+
let netutilsForwards = [];
|
|
7570
|
+
if (netutilsEnabled) {
|
|
7571
|
+
if (netutilsExposeAll) {
|
|
7572
|
+
netutilsForwards = buildNetutilsExposeAllForwards("envsync");
|
|
7573
|
+
logInfo("Netutils exposes all preset (auto-generated):");
|
|
7574
|
+
for (const forward of netutilsForwards) {
|
|
7575
|
+
console.log(` ${forward.service}:${forward.service_port} -> ${forward.host_port} (${forward.protocol})`);
|
|
7576
|
+
}
|
|
7577
|
+
} else {
|
|
7578
|
+
netutilsForwards = parseNetutilsForwardsFromInput(
|
|
7579
|
+
await ask(
|
|
7580
|
+
"Netutils forwards (format service:service_port:host_port[:protocol], comma-separated)",
|
|
7581
|
+
"postgres:5432:15432:tcp,keycloak:8080:18080:tcp"
|
|
7582
|
+
),
|
|
7583
|
+
"envsync"
|
|
7584
|
+
);
|
|
7585
|
+
}
|
|
7586
|
+
}
|
|
7476
7587
|
const licenseServerUrl = await ask("Enterprise license server URL", DEFAULT_ENTERPRISE_LICENSE_SERVER_URL);
|
|
7477
7588
|
const licenseKey = licenseServerUrl ? await ask("Enterprise license key", "") : "";
|
|
7478
7589
|
const certificateBundleFile = licenseServerUrl ? "" : await ask("Enterprise certificate bundle file (optional)", "");
|