UNPKG

@mesh-tech/mesh-cli

Version:

CLI for Mesh platform development utilities

61 lines (60 loc) 2.05 kB
import { execFileSync } from "node:child_process"; import * as fs from "node:fs"; import * as path from "node:path"; import { reserveSsmLocalPortCandidate, preferredSsmLocalPort } from "../commands/dev.js"; import { CONFIG_DIR, atomicWriteFileSync } from "../commands/login.js"; export const PORT_BLOCK = 3000; export function tenantPortIndex(tenant, registryPath) { const p = registryPath ?? path.join(CONFIG_DIR, "tailscale", "port-registry.json"); let reg; try { reg = JSON.parse(fs.readFileSync(p, "utf8")); } catch { reg = { mesh: 0 }; } if (tenant in reg) return reg[tenant]; const idx = Math.max(-1, ...Object.values(reg)) + 1; reg[tenant] = idx; fs.mkdirSync(path.dirname(p), { recursive: true }); atomicWriteFileSync(p, JSON.stringify(reg, null, 2), 0o600); return idx; } export const TUNNEL_NAME_BY_BASTION_KEY = { "temporal-frontend": "temporal", "temporal-ui": "temporal-ui", rds: "rds", }; export function resolveTunnelTargets(services, resolveIp, portOffset = 0) { const reserved = new Set(); const targets = []; for (const [key, svc] of Object.entries(services)) { const name = TUNNEL_NAME_BY_BASTION_KEY[key]; if (!name) continue; const targetIp = resolveIp(svc.host); if (!targetIp) continue; const localPort = reserveSsmLocalPortCandidate(svc.port, reserved, preferredSsmLocalPort(svc.port) + portOffset); targets.push({ name, localPort, targetHost: svc.host, targetIp, remotePort: svc.port }); } return targets; } export function resolveElbIp(host) { try { const out = execFileSync("dig", ["+short", host, "@1.1.1.1"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], }); const ip = out .trim() .split("\n") .map((l) => l.trim()) .find((l) => /^\d+\.\d+\.\d+\.\d+$/.test(l)); return ip ?? null; } catch { return null; } }