@cardelli/ambit 0.1.5 → 0.2.1
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 +261 -0
- package/esm/cli/commands/create/index.d.ts +2 -0
- package/esm/cli/commands/create/index.d.ts.map +1 -0
- package/esm/cli/commands/create/index.js +292 -0
- package/esm/cli/commands/create/machine.d.ts +33 -0
- package/esm/cli/commands/create/machine.d.ts.map +1 -0
- package/esm/cli/commands/create/machine.js +162 -0
- package/esm/cli/commands/deploy/index.d.ts +2 -0
- package/esm/cli/commands/deploy/index.d.ts.map +1 -0
- package/esm/cli/commands/deploy/index.js +290 -0
- package/esm/cli/commands/deploy/machine.d.ts +52 -0
- package/esm/cli/commands/deploy/machine.d.ts.map +1 -0
- package/esm/cli/commands/deploy/machine.js +116 -0
- package/esm/cli/commands/deploy/modes.d.ts +18 -0
- package/esm/cli/commands/deploy/modes.d.ts.map +1 -0
- package/esm/cli/commands/deploy/modes.js +152 -0
- package/esm/cli/commands/destroy/app.d.ts +2 -0
- package/esm/cli/commands/destroy/app.d.ts.map +1 -0
- package/esm/cli/commands/destroy/app.js +173 -0
- package/esm/cli/commands/destroy/index.d.ts +2 -0
- package/esm/cli/commands/destroy/index.d.ts.map +1 -0
- package/esm/cli/commands/destroy/index.js +63 -0
- package/esm/cli/commands/destroy/network.d.ts +2 -0
- package/esm/cli/commands/destroy/network.d.ts.map +1 -0
- package/esm/cli/commands/destroy/network.js +210 -0
- package/esm/cli/commands/doctor.d.ts.map +1 -0
- package/esm/cli/commands/doctor.js +295 -0
- package/esm/{src/cli → cli}/commands/list.d.ts.map +1 -1
- package/esm/{src/cli → cli}/commands/list.js +39 -54
- package/esm/cli/commands/status.d.ts.map +1 -0
- package/esm/cli/commands/status.js +331 -0
- package/esm/cli/mod.d.ts.map +1 -0
- package/esm/{src/cli → cli}/mod.js +4 -4
- package/esm/deno.d.ts +4 -18
- package/esm/deno.js +5 -19
- package/esm/deps/jsr.io/@std/path/1.1.4/constants.d.ts +1 -1
- package/esm/lib/args.d.ts +11 -0
- package/esm/lib/args.d.ts.map +1 -0
- package/esm/lib/args.js +28 -0
- package/esm/lib/cli.d.ts +0 -1
- package/esm/lib/cli.d.ts.map +1 -1
- package/esm/lib/cli.js +0 -1
- package/esm/lib/command.d.ts +0 -3
- package/esm/lib/command.d.ts.map +1 -1
- package/esm/lib/command.js +2 -13
- package/esm/lib/machine.d.ts +11 -0
- package/esm/lib/machine.d.ts.map +1 -0
- package/esm/lib/machine.js +15 -0
- package/esm/lib/output.d.ts +2 -1
- package/esm/lib/output.d.ts.map +1 -1
- package/esm/lib/output.js +21 -3
- package/esm/lib/result.d.ts +0 -1
- package/esm/lib/result.d.ts.map +1 -1
- package/esm/lib/result.js +0 -1
- package/esm/main.d.ts +6 -6
- package/esm/main.d.ts.map +1 -1
- package/esm/main.js +7 -9
- package/esm/providers/fly.d.ts +81 -0
- package/esm/providers/fly.d.ts.map +1 -0
- package/esm/providers/fly.js +372 -0
- package/esm/providers/tailscale.d.ts +31 -0
- package/esm/providers/tailscale.d.ts.map +1 -0
- package/esm/providers/tailscale.js +150 -0
- package/esm/{src/schemas → schemas}/fly.d.ts +1 -11
- package/esm/schemas/fly.d.ts.map +1 -0
- package/esm/{src/schemas → schemas}/fly.js +14 -56
- package/esm/{src/schemas → schemas}/tailscale.d.ts +1 -2
- package/esm/schemas/tailscale.d.ts.map +1 -0
- package/esm/{src/schemas → schemas}/tailscale.js +2 -3
- package/esm/src/{docker/router → router}/Dockerfile +0 -11
- package/esm/src/{docker/router → router}/start.sh +18 -9
- package/esm/util/constants.d.ts +13 -0
- package/esm/util/constants.d.ts.map +1 -0
- package/esm/util/constants.js +34 -0
- package/esm/{src → util}/credentials.d.ts +0 -1
- package/esm/util/credentials.d.ts.map +1 -0
- package/esm/{src → util}/credentials.js +3 -5
- package/esm/{src → util}/discovery.d.ts +16 -3
- package/esm/util/discovery.d.ts.map +1 -0
- package/esm/{src → util}/discovery.js +24 -15
- package/esm/util/fly-transforms.d.ts +27 -0
- package/esm/util/fly-transforms.d.ts.map +1 -0
- package/esm/util/fly-transforms.js +87 -0
- package/esm/{src → util}/guard.d.ts +1 -2
- package/esm/util/guard.d.ts.map +1 -0
- package/esm/{src → util}/guard.js +27 -27
- package/esm/util/naming.d.ts +5 -0
- package/esm/util/naming.d.ts.map +1 -0
- package/esm/util/naming.js +12 -0
- package/esm/{src → util}/resolve.d.ts +2 -3
- package/esm/util/resolve.d.ts.map +1 -0
- package/esm/{src → util}/resolve.js +1 -2
- package/esm/util/session.d.ts +16 -0
- package/esm/util/session.d.ts.map +1 -0
- package/esm/util/session.js +19 -0
- package/esm/util/tailscale-local.d.ts +13 -0
- package/esm/util/tailscale-local.d.ts.map +1 -0
- package/esm/util/tailscale-local.js +63 -0
- package/esm/{src → util}/template.d.ts +0 -1
- package/esm/util/template.d.ts.map +1 -0
- package/esm/{src → util}/template.js +0 -1
- package/package.json +1 -49
- package/esm/lib/paths.d.ts +0 -3
- package/esm/lib/paths.d.ts.map +0 -1
- package/esm/lib/paths.js +0 -5
- package/esm/src/cli/commands/create.d.ts +0 -2
- package/esm/src/cli/commands/create.d.ts.map +0 -1
- package/esm/src/cli/commands/create.js +0 -308
- package/esm/src/cli/commands/deploy.d.ts +0 -2
- package/esm/src/cli/commands/deploy.d.ts.map +0 -1
- package/esm/src/cli/commands/deploy.js +0 -430
- package/esm/src/cli/commands/destroy.d.ts +0 -2
- package/esm/src/cli/commands/destroy.d.ts.map +0 -1
- package/esm/src/cli/commands/destroy.js +0 -340
- package/esm/src/cli/commands/doctor.d.ts.map +0 -1
- package/esm/src/cli/commands/doctor.js +0 -141
- package/esm/src/cli/commands/status.d.ts.map +0 -1
- package/esm/src/cli/commands/status.js +0 -152
- package/esm/src/cli/mod.d.ts.map +0 -1
- package/esm/src/credentials.d.ts.map +0 -1
- package/esm/src/discovery.d.ts.map +0 -1
- package/esm/src/guard.d.ts.map +0 -1
- package/esm/src/providers/fly.d.ts +0 -76
- package/esm/src/providers/fly.d.ts.map +0 -1
- package/esm/src/providers/fly.js +0 -407
- package/esm/src/providers/tailscale.d.ts +0 -31
- package/esm/src/providers/tailscale.d.ts.map +0 -1
- package/esm/src/providers/tailscale.js +0 -189
- package/esm/src/resolve.d.ts.map +0 -1
- package/esm/src/schemas/config.d.ts +0 -5
- package/esm/src/schemas/config.d.ts.map +0 -1
- package/esm/src/schemas/config.js +0 -22
- package/esm/src/schemas/fly.d.ts.map +0 -1
- package/esm/src/schemas/tailscale.d.ts.map +0 -1
- package/esm/src/template.d.ts.map +0 -1
- /package/esm/{src/cli → cli}/commands/doctor.d.ts +0 -0
- /package/esm/{src/cli → cli}/commands/list.d.ts +0 -0
- /package/esm/{src/cli → cli}/commands/status.d.ts +0 -0
- /package/esm/{src/cli → cli}/mod.d.ts +0 -0
- /package/esm/src/{docker/router → router}/fly.toml +0 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Doctor Command - Verify Environment and Infrastructure Health
|
|
3
|
+
// =============================================================================
|
|
4
|
+
import { parseArgs } from "../../deps/jsr.io/@std/cli/1.0.28/mod.js";
|
|
5
|
+
import { bold } from "../../lib/cli.js";
|
|
6
|
+
import { checkArgs } from "../../lib/args.js";
|
|
7
|
+
import { createOutput } from "../../lib/output.js";
|
|
8
|
+
import { runCommand } from "../../lib/command.js";
|
|
9
|
+
import { registerCommand } from "../mod.js";
|
|
10
|
+
import { isAcceptRoutesEnabled, isTailscaleInstalled, } from "../../util/tailscale-local.js";
|
|
11
|
+
import { findRouterApp, findWorkloadApp, getRouterMachineInfo, getRouterTailscaleInfo, listRouterApps, } from "../../util/discovery.js";
|
|
12
|
+
import { initSession } from "../../util/session.js";
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// Reporter
|
|
15
|
+
// =============================================================================
|
|
16
|
+
const makeReporter = (results, out) => (name, ok, hint) => {
|
|
17
|
+
results.push({ name, ok, hint });
|
|
18
|
+
if (ok) {
|
|
19
|
+
out.ok(name);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
out.err(name);
|
|
23
|
+
if (hint)
|
|
24
|
+
out.dim(` ${hint}`);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Stage 1: Local Checks
|
|
29
|
+
// =============================================================================
|
|
30
|
+
const stageLocalChecks = async (report) => {
|
|
31
|
+
report("Tailscale Installed", await isTailscaleInstalled(), "Install from https://tailscale.com/download");
|
|
32
|
+
const tsStatus = await runCommand(["tailscale", "status", "--json"]);
|
|
33
|
+
let tsConnected = false;
|
|
34
|
+
if (tsStatus.ok) {
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(tsStatus.stdout);
|
|
37
|
+
tsConnected = parsed.BackendState === "Running";
|
|
38
|
+
}
|
|
39
|
+
catch { /* ignore */ }
|
|
40
|
+
}
|
|
41
|
+
report("Tailscale Connected", tsConnected, "Run: tailscale up");
|
|
42
|
+
report("Accept Routes Enabled", await isAcceptRoutesEnabled(), "Run: sudo tailscale set --accept-routes");
|
|
43
|
+
};
|
|
44
|
+
// =============================================================================
|
|
45
|
+
// Router Health Helper (shared by network and app stages)
|
|
46
|
+
// =============================================================================
|
|
47
|
+
const checkRouter = async (fly, tailscale, report, app) => {
|
|
48
|
+
const { network } = app;
|
|
49
|
+
report(`Router Exists (${network})`, true);
|
|
50
|
+
const machine = await getRouterMachineInfo(fly, app.appName);
|
|
51
|
+
report(`Router Running (${network})`, machine?.state === "started", machine ? `Machine State: ${machine.state}` : "No Machine Found");
|
|
52
|
+
const ts = await getRouterTailscaleInfo(tailscale, app.appName);
|
|
53
|
+
report(`Router in Tailnet (${network})`, ts !== null, "Router May Still Be Starting, or Check Router Logs");
|
|
54
|
+
if (ts) {
|
|
55
|
+
const device = await tailscale.devices.getByHostname(app.appName);
|
|
56
|
+
if (device) {
|
|
57
|
+
const routes = await tailscale.routes.get(device.id);
|
|
58
|
+
if (routes && routes.unapproved.length > 0) {
|
|
59
|
+
await tailscale.routes.approve(device.id, routes.advertised);
|
|
60
|
+
report(`Routes Approved (${network})`, true, `Approved: ${routes.unapproved.join(", ")}`);
|
|
61
|
+
}
|
|
62
|
+
else if (routes && routes.advertised.length > 0) {
|
|
63
|
+
report(`Routes Approved (${network})`, true);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
report(`Routes Approved (${network})`, false, "No Routes Advertised — Router May Need Restart");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
// =============================================================================
|
|
72
|
+
// Stage 3a: Network Checks
|
|
73
|
+
// =============================================================================
|
|
74
|
+
const stageNetworkChecks = async (fly, tailscale, org, report, network) => {
|
|
75
|
+
if (network) {
|
|
76
|
+
const app = await findRouterApp(fly, org, network);
|
|
77
|
+
if (!app) {
|
|
78
|
+
report(`Router Exists (${network})`, false, `Create with: ambit create ${network}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
await checkRouter(fly, tailscale, report, app);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const routerApps = await listRouterApps(fly, org);
|
|
86
|
+
if (routerApps.length === 0) {
|
|
87
|
+
report("Routers Discovered", false, "Run: ambit create <network>");
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
for (const app of routerApps) {
|
|
91
|
+
await checkRouter(fly, tailscale, report, app);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
// =============================================================================
|
|
97
|
+
// Stage 3b: App Checks
|
|
98
|
+
// =============================================================================
|
|
99
|
+
const stageAppChecks = async (fly, tailscale, org, report, app, network) => {
|
|
100
|
+
const workload = await findWorkloadApp(fly, org, app, network);
|
|
101
|
+
if (!workload) {
|
|
102
|
+
report(`App Exists (${app}.${network})`, false, `Deploy with: ambit deploy ${app}.${network}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
report(`App Exists (${app}.${network})`, true);
|
|
106
|
+
const machines = await fly.machines.list(workload.appName);
|
|
107
|
+
const started = machines.find((m) => m.state === "started");
|
|
108
|
+
report(`App Running (${app}.${network})`, started !== undefined, machines.length > 0
|
|
109
|
+
? `Machine State: ${machines[0].state}`
|
|
110
|
+
: "No Machines Found");
|
|
111
|
+
const router = await findRouterApp(fly, org, network);
|
|
112
|
+
if (!router) {
|
|
113
|
+
report(`Router Exists (${network})`, false, `Create with: ambit create ${network}`);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
await checkRouter(fly, tailscale, report, router);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
// =============================================================================
|
|
120
|
+
// Stage 4: Summary
|
|
121
|
+
// =============================================================================
|
|
122
|
+
const stageSummary = (out, results) => {
|
|
123
|
+
const issues = results.filter((r) => !r.ok).length;
|
|
124
|
+
if (issues === 0) {
|
|
125
|
+
out.done({ checks: results });
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
out.fail(`${issues} Issue${issues > 1 ? "s" : ""} Found`, {
|
|
129
|
+
checks: results,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
out.blank();
|
|
133
|
+
out.text(issues === 0 ? "All Checks Passed." : `${issues} Issue${issues > 1 ? "s" : ""} Found.`);
|
|
134
|
+
out.blank();
|
|
135
|
+
out.print();
|
|
136
|
+
};
|
|
137
|
+
// =============================================================================
|
|
138
|
+
// Doctor Network
|
|
139
|
+
// =============================================================================
|
|
140
|
+
const doctorNetwork = async (argv) => {
|
|
141
|
+
const opts = { string: ["network", "org"], boolean: ["help", "json"] };
|
|
142
|
+
const args = parseArgs(argv, opts);
|
|
143
|
+
checkArgs(args, opts, "ambit doctor network");
|
|
144
|
+
if (args.help) {
|
|
145
|
+
console.log(`
|
|
146
|
+
${bold("ambit doctor network")} - Check Router Health
|
|
147
|
+
|
|
148
|
+
${bold("USAGE")}
|
|
149
|
+
ambit doctor network [<name>] [--org <org>] [--json]
|
|
150
|
+
ambit doctor [--network <name>] [--org <org>] [--json]
|
|
151
|
+
|
|
152
|
+
${bold("OPTIONS")}
|
|
153
|
+
<name> Router network to check (checks all if omitted)
|
|
154
|
+
--network <name> Alias for positional <name>
|
|
155
|
+
--org <org> Fly.io organization slug
|
|
156
|
+
--json Output as JSON
|
|
157
|
+
|
|
158
|
+
${bold("CHECKS")}
|
|
159
|
+
- Tailscale CLI installed and connected
|
|
160
|
+
- Accept-routes enabled
|
|
161
|
+
- Router created and running
|
|
162
|
+
- Router visible in tailnet
|
|
163
|
+
- Subnet routes approved
|
|
164
|
+
`);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const out = createOutput(args.json);
|
|
168
|
+
out.blank().header("ambit Doctor: Network").blank();
|
|
169
|
+
const results = [];
|
|
170
|
+
const report = makeReporter(results, out);
|
|
171
|
+
const network = (typeof args._[0] === "string" ? args._[0] : undefined) || args.network;
|
|
172
|
+
const { fly, tailscale, org } = await initSession(out, {
|
|
173
|
+
json: args.json,
|
|
174
|
+
org: args.org,
|
|
175
|
+
});
|
|
176
|
+
await stageLocalChecks(report);
|
|
177
|
+
await stageNetworkChecks(fly, tailscale, org, report, network);
|
|
178
|
+
stageSummary(out, results);
|
|
179
|
+
};
|
|
180
|
+
// =============================================================================
|
|
181
|
+
// Doctor App
|
|
182
|
+
// =============================================================================
|
|
183
|
+
const doctorApp = async (argv) => {
|
|
184
|
+
const opts = { string: ["network", "org"], boolean: ["help", "json"] };
|
|
185
|
+
const args = parseArgs(argv, opts);
|
|
186
|
+
checkArgs(args, opts, "ambit doctor app");
|
|
187
|
+
if (args.help) {
|
|
188
|
+
console.log(`
|
|
189
|
+
${bold("ambit doctor app")} - Check App Health
|
|
190
|
+
|
|
191
|
+
${bold("USAGE")}
|
|
192
|
+
ambit doctor app <app>.<network> [--org <org>] [--json]
|
|
193
|
+
ambit doctor app <app> --network <name> [--org <org>] [--json]
|
|
194
|
+
|
|
195
|
+
${bold("OPTIONS")}
|
|
196
|
+
--network <name> Target network (if not using dot syntax)
|
|
197
|
+
--org <org> Fly.io organization slug
|
|
198
|
+
--json Output as JSON
|
|
199
|
+
|
|
200
|
+
${bold("CHECKS")}
|
|
201
|
+
- Tailscale CLI installed and connected
|
|
202
|
+
- Accept-routes enabled
|
|
203
|
+
- App deployed and running
|
|
204
|
+
- Router exists and is healthy
|
|
205
|
+
- Subnet routes approved
|
|
206
|
+
`);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const out = createOutput(args.json);
|
|
210
|
+
const appArg = args._[0];
|
|
211
|
+
if (!appArg || typeof appArg !== "string") {
|
|
212
|
+
return out.die("Missing App Name. Usage: ambit doctor app <app>.<network>");
|
|
213
|
+
}
|
|
214
|
+
let app;
|
|
215
|
+
let network;
|
|
216
|
+
if (appArg.includes(".")) {
|
|
217
|
+
const parts = appArg.split(".");
|
|
218
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
219
|
+
return out.die(`'${appArg}' Should Have Exactly One Dot, Like my-app.my-network`);
|
|
220
|
+
}
|
|
221
|
+
app = parts[0];
|
|
222
|
+
network = parts[1];
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
app = appArg;
|
|
226
|
+
if (!args.network) {
|
|
227
|
+
return out.die(`Missing Network. Use: ambit doctor app ${app}.<network>`);
|
|
228
|
+
}
|
|
229
|
+
network = args.network;
|
|
230
|
+
}
|
|
231
|
+
out.blank().header(`ambit Doctor: App ${app}.${network}`).blank();
|
|
232
|
+
const results = [];
|
|
233
|
+
const report = makeReporter(results, out);
|
|
234
|
+
const { fly, tailscale, org } = await initSession(out, {
|
|
235
|
+
json: args.json,
|
|
236
|
+
org: args.org,
|
|
237
|
+
});
|
|
238
|
+
await stageLocalChecks(report);
|
|
239
|
+
await stageAppChecks(fly, tailscale, org, report, app, network);
|
|
240
|
+
stageSummary(out, results);
|
|
241
|
+
};
|
|
242
|
+
// =============================================================================
|
|
243
|
+
// Top-Level Help
|
|
244
|
+
// =============================================================================
|
|
245
|
+
const showDoctorHelp = () => {
|
|
246
|
+
console.log(`
|
|
247
|
+
${bold("ambit doctor")} - Verify Environment and Infrastructure Health
|
|
248
|
+
|
|
249
|
+
${bold("USAGE")}
|
|
250
|
+
ambit doctor [options]
|
|
251
|
+
ambit doctor network [<name>] [options]
|
|
252
|
+
ambit doctor app <app>.<network> [options]
|
|
253
|
+
|
|
254
|
+
${bold("SUBCOMMANDS")}
|
|
255
|
+
network Check router(s) health — default when no subcommand given
|
|
256
|
+
app Check a specific app's health
|
|
257
|
+
|
|
258
|
+
${bold("OPTIONS")}
|
|
259
|
+
--org <org> Fly.io organization slug
|
|
260
|
+
--json Output as JSON
|
|
261
|
+
|
|
262
|
+
${bold("EXAMPLES")}
|
|
263
|
+
ambit doctor
|
|
264
|
+
ambit doctor network
|
|
265
|
+
ambit doctor network browsers
|
|
266
|
+
ambit doctor app my-app.browsers
|
|
267
|
+
|
|
268
|
+
Run 'ambit doctor network --help' or 'ambit doctor app --help' for details.
|
|
269
|
+
`);
|
|
270
|
+
};
|
|
271
|
+
// =============================================================================
|
|
272
|
+
// Dispatcher
|
|
273
|
+
// =============================================================================
|
|
274
|
+
const doctor = async (argv) => {
|
|
275
|
+
const subcommand = typeof argv[0] === "string" ? argv[0] : undefined;
|
|
276
|
+
if (subcommand === "network")
|
|
277
|
+
return doctorNetwork(argv.slice(1));
|
|
278
|
+
if (subcommand === "app")
|
|
279
|
+
return doctorApp(argv.slice(1));
|
|
280
|
+
const args = parseArgs(argv, { boolean: ["help"] });
|
|
281
|
+
if (args.help) {
|
|
282
|
+
showDoctorHelp();
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
return doctorNetwork(argv);
|
|
286
|
+
};
|
|
287
|
+
// =============================================================================
|
|
288
|
+
// Register Command
|
|
289
|
+
// =============================================================================
|
|
290
|
+
registerCommand({
|
|
291
|
+
name: "doctor",
|
|
292
|
+
description: "Check that Tailscale and the router are working correctly",
|
|
293
|
+
usage: "ambit doctor [network|app] [<name>] [--org <org>] [--json]",
|
|
294
|
+
run: doctor,
|
|
295
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":""}
|
|
@@ -1,53 +1,19 @@
|
|
|
1
1
|
// =============================================================================
|
|
2
2
|
// List Command - List All Discovered Routers
|
|
3
3
|
// =============================================================================
|
|
4
|
-
import { parseArgs } from "
|
|
5
|
-
import { Table } from "
|
|
6
|
-
import { bold } from "
|
|
7
|
-
import {
|
|
4
|
+
import { parseArgs } from "../../deps/jsr.io/@std/cli/1.0.28/mod.js";
|
|
5
|
+
import { Table } from "../../deps/jsr.io/@cliffy/table/1.0.0/mod.js";
|
|
6
|
+
import { bold } from "../../lib/cli.js";
|
|
7
|
+
import { checkArgs } from "../../lib/args.js";
|
|
8
|
+
import { createOutput } from "../../lib/output.js";
|
|
8
9
|
import { registerCommand } from "../mod.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { checkDependencies } from "../../credentials.js";
|
|
12
|
-
import { getRouterMachineInfo, getRouterTailscaleInfo, listRouterApps, } from "../../discovery.js";
|
|
13
|
-
import { resolveOrg } from "../../resolve.js";
|
|
10
|
+
import { discoverRouters, } from "../../util/discovery.js";
|
|
11
|
+
import { initSession } from "../../util/session.js";
|
|
14
12
|
// =============================================================================
|
|
15
|
-
//
|
|
13
|
+
// Stage: Render
|
|
16
14
|
// =============================================================================
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
string: ["org"],
|
|
20
|
-
boolean: ["help", "json"],
|
|
21
|
-
});
|
|
22
|
-
if (args.help) {
|
|
23
|
-
console.log(`
|
|
24
|
-
${bold("ambit list")} - List All Discovered Routers
|
|
25
|
-
|
|
26
|
-
${bold("USAGE")}
|
|
27
|
-
ambit list [--org <org>] [--json]
|
|
28
|
-
|
|
29
|
-
${bold("OPTIONS")}
|
|
30
|
-
--org <org> Fly.io organization slug
|
|
31
|
-
--json Output as JSON
|
|
32
|
-
`);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
const out = createOutput(args.json);
|
|
36
|
-
// =========================================================================
|
|
37
|
-
// Prerequisites
|
|
38
|
-
// =========================================================================
|
|
39
|
-
const { tailscaleKey } = await checkDependencies(out);
|
|
40
|
-
const fly = createFlyProvider();
|
|
41
|
-
await fly.ensureAuth({ interactive: !args.json });
|
|
42
|
-
const tailscale = createTailscaleProvider("-", tailscaleKey);
|
|
43
|
-
const org = await resolveOrg(fly, args, out);
|
|
44
|
-
// =========================================================================
|
|
45
|
-
// Discover Routers
|
|
46
|
-
// =========================================================================
|
|
47
|
-
const spinner = out.spinner("Discovering Routers");
|
|
48
|
-
const routerApps = await listRouterApps(fly, org);
|
|
49
|
-
spinner.success(`Found ${routerApps.length} Router${routerApps.length !== 1 ? "s" : ""}`);
|
|
50
|
-
if (routerApps.length === 0) {
|
|
15
|
+
const stageRender = (out, routers) => {
|
|
16
|
+
if (routers.length === 0) {
|
|
51
17
|
out.blank()
|
|
52
18
|
.text("No Routers Found.")
|
|
53
19
|
.dim(" Create one with: ambit create <network>")
|
|
@@ -56,19 +22,10 @@ ${bold("OPTIONS")}
|
|
|
56
22
|
out.print();
|
|
57
23
|
return;
|
|
58
24
|
}
|
|
59
|
-
const routers = [];
|
|
60
|
-
for (const app of routerApps) {
|
|
61
|
-
const machine = await getRouterMachineInfo(fly, app.appName);
|
|
62
|
-
const ts = await getRouterTailscaleInfo(tailscale, app.appName);
|
|
63
|
-
routers.push({ ...app, machine, tailscale: ts });
|
|
64
|
-
}
|
|
65
|
-
// =========================================================================
|
|
66
|
-
// Render
|
|
67
|
-
// =========================================================================
|
|
68
25
|
out.blank().header("Routers").blank();
|
|
69
26
|
const rows = routers.map((r) => {
|
|
70
27
|
const tsStatus = r.tailscale
|
|
71
|
-
? r.tailscale.online ? "online" : "offline"
|
|
28
|
+
? (r.tailscale.online ? "online" : "offline")
|
|
72
29
|
: "not found";
|
|
73
30
|
const tag = r.tailscale?.tags?.[0] ?? "unknown";
|
|
74
31
|
return [
|
|
@@ -91,6 +48,34 @@ ${bold("OPTIONS")}
|
|
|
91
48
|
out.print();
|
|
92
49
|
};
|
|
93
50
|
// =============================================================================
|
|
51
|
+
// List Command
|
|
52
|
+
// =============================================================================
|
|
53
|
+
const list = async (argv) => {
|
|
54
|
+
const opts = { string: ["org"], boolean: ["help", "json"] };
|
|
55
|
+
const args = parseArgs(argv, opts);
|
|
56
|
+
checkArgs(args, opts, "ambit list");
|
|
57
|
+
if (args.help) {
|
|
58
|
+
console.log(`
|
|
59
|
+
${bold("ambit list")} - List All Discovered Routers
|
|
60
|
+
|
|
61
|
+
${bold("USAGE")}
|
|
62
|
+
ambit list [--org <org>] [--json]
|
|
63
|
+
|
|
64
|
+
${bold("OPTIONS")}
|
|
65
|
+
--org <org> Fly.io organization slug
|
|
66
|
+
--json Output as JSON
|
|
67
|
+
`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const out = createOutput(args.json);
|
|
71
|
+
const { fly, tailscale, org } = await initSession(out, {
|
|
72
|
+
json: args.json,
|
|
73
|
+
org: args.org,
|
|
74
|
+
});
|
|
75
|
+
const routers = await discoverRouters(out, fly, tailscale, org);
|
|
76
|
+
stageRender(out, routers);
|
|
77
|
+
};
|
|
78
|
+
// =============================================================================
|
|
94
79
|
// Register Command
|
|
95
80
|
// =============================================================================
|
|
96
81
|
registerCommand({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":""}
|