@cardelli/ambit 0.3.0 → 0.3.2
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 +32 -13
- package/esm/cli/commands/create/index.js +10 -28
- package/esm/cli/commands/create/machine.d.ts +2 -1
- package/esm/cli/commands/create/machine.d.ts.map +1 -1
- package/esm/cli/commands/create/machine.js +69 -28
- package/esm/cli/commands/list/apps.d.ts +2 -0
- package/esm/cli/commands/list/apps.d.ts.map +1 -0
- package/esm/cli/commands/list/apps.js +72 -0
- package/esm/cli/commands/list/index.d.ts +2 -0
- package/esm/cli/commands/list/index.d.ts.map +1 -0
- package/esm/cli/commands/list/index.js +62 -0
- package/esm/cli/commands/list/networks.d.ts +2 -0
- package/esm/cli/commands/list/networks.d.ts.map +1 -0
- package/esm/cli/commands/{list.js → list/networks.js} +17 -27
- package/esm/cli/commands/status/app.d.ts +2 -0
- package/esm/cli/commands/status/app.d.ts.map +1 -0
- package/esm/cli/commands/status/app.js +141 -0
- package/esm/cli/commands/status/index.d.ts +2 -0
- package/esm/cli/commands/status/index.d.ts.map +1 -0
- package/esm/cli/commands/status/index.js +68 -0
- package/esm/cli/commands/status/network.d.ts +2 -0
- package/esm/cli/commands/status/network.d.ts.map +1 -0
- package/esm/cli/commands/status/network.js +104 -0
- package/esm/cli/commands/status/networks.d.ts +2 -0
- package/esm/cli/commands/status/networks.d.ts.map +1 -0
- package/esm/cli/commands/status/networks.js +62 -0
- package/esm/deno.js +1 -1
- package/esm/main.d.ts +2 -2
- package/esm/main.d.ts.map +1 -1
- package/esm/main.js +5 -2
- package/esm/router/start.sh +7 -4
- package/esm/schemas/fly.d.ts +84 -4
- package/esm/schemas/fly.d.ts.map +1 -1
- package/esm/schemas/fly.js +34 -2
- package/esm/util/constants.d.ts +0 -1
- package/esm/util/constants.d.ts.map +1 -1
- package/esm/util/constants.js +0 -1
- package/esm/util/discovery.d.ts +4 -1
- package/esm/util/discovery.d.ts.map +1 -1
- package/esm/util/discovery.js +3 -0
- package/package.json +1 -1
- package/esm/cli/commands/list.d.ts +0 -2
- package/esm/cli/commands/list.d.ts.map +0 -1
- package/esm/cli/commands/status.d.ts +0 -2
- package/esm/cli/commands/status.d.ts.map +0 -1
- package/esm/cli/commands/status.js +0 -334
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Status App — Show App Status
|
|
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 { findRouterApp, findWorkloadApp, getRouterMachineInfo, getRouterTailscaleInfo, } from "../../../util/discovery.js";
|
|
9
|
+
import { initSession } from "../../../util/session.js";
|
|
10
|
+
import { SOCKS_PROXY_PORT } from "../../../util/constants.js";
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Detailed App View
|
|
13
|
+
// =============================================================================
|
|
14
|
+
const stageAppStatus = async (fly, tailscale, app, network, org, json) => {
|
|
15
|
+
const out = createOutput(json);
|
|
16
|
+
const workload = await findWorkloadApp(fly, org, app, network);
|
|
17
|
+
if (!workload) {
|
|
18
|
+
return out.die(`App '${app}' Not Found on Network '${network}'`);
|
|
19
|
+
}
|
|
20
|
+
const machines = await fly.machines.list(workload.appName);
|
|
21
|
+
const ips = await fly.ips.list(workload.appName);
|
|
22
|
+
const mappedMachines = machines.map((m) => ({
|
|
23
|
+
id: m.id,
|
|
24
|
+
region: m.region,
|
|
25
|
+
state: m.state,
|
|
26
|
+
privateIp: m.private_ip,
|
|
27
|
+
}));
|
|
28
|
+
const mappedIps = ips.map((ip) => ({
|
|
29
|
+
address: ip.Address,
|
|
30
|
+
type: ip.Type,
|
|
31
|
+
network: ip.Network?.Name,
|
|
32
|
+
}));
|
|
33
|
+
const router = await findRouterApp(fly, org, network);
|
|
34
|
+
out.blank()
|
|
35
|
+
.header(`Ambit Status: ${app}.${network}`)
|
|
36
|
+
.blank()
|
|
37
|
+
.text(` App: ${bold(app)}`)
|
|
38
|
+
.text(` Network: ${network}`)
|
|
39
|
+
.text(` Fly App: ${workload.appName}`)
|
|
40
|
+
.text(` Status: ${workload.status}`)
|
|
41
|
+
.blank();
|
|
42
|
+
if (machines.length === 0) {
|
|
43
|
+
out.text(" Machines: None");
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
out.header(" Machines").blank();
|
|
47
|
+
for (const m of machines) {
|
|
48
|
+
out.text(` ${m.id} ${m.region} ${m.state}${m.private_ip ? ` ${m.private_ip}` : ""}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
out.blank();
|
|
52
|
+
const flycastIps = ips.filter((ip) => ip.Type === "private_v6");
|
|
53
|
+
const publicIps = ips.filter((ip) => ip.Type !== "private_v6");
|
|
54
|
+
if (flycastIps.length > 0) {
|
|
55
|
+
out.header(" Flycast IPs").blank();
|
|
56
|
+
for (const ip of flycastIps) {
|
|
57
|
+
out.text(` ${ip.Address} (network: ${ip.Network?.Name ?? "default"})`);
|
|
58
|
+
}
|
|
59
|
+
out.blank();
|
|
60
|
+
}
|
|
61
|
+
if (publicIps.length > 0) {
|
|
62
|
+
out.header(" Public IPs (Warning: Ambit Apps Should Not Have Public IPs)")
|
|
63
|
+
.blank();
|
|
64
|
+
for (const ip of publicIps) {
|
|
65
|
+
out.text(` ${ip.Address} ${ip.Type}`);
|
|
66
|
+
}
|
|
67
|
+
out.blank();
|
|
68
|
+
}
|
|
69
|
+
if (router) {
|
|
70
|
+
const routerMachine = await getRouterMachineInfo(fly, router.appName);
|
|
71
|
+
const ts = await getRouterTailscaleInfo(tailscale, router.appName);
|
|
72
|
+
out.header(" Router").blank()
|
|
73
|
+
.text(` App: ${router.appName}`)
|
|
74
|
+
.text(` State: ${routerMachine?.state ?? "unknown"}`)
|
|
75
|
+
.text(` Tailscale: ${ts ? (ts.online ? "online" : "offline") : "not found"}`);
|
|
76
|
+
if (routerMachine?.privateIp) {
|
|
77
|
+
out.text(` SOCKS Proxy: socks5://[${routerMachine.privateIp}]:${SOCKS_PROXY_PORT}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
out.text(" Router: Not Found");
|
|
82
|
+
}
|
|
83
|
+
out.blank();
|
|
84
|
+
out.done({
|
|
85
|
+
app,
|
|
86
|
+
network,
|
|
87
|
+
flyAppName: workload.appName,
|
|
88
|
+
machines: mappedMachines,
|
|
89
|
+
ips: mappedIps,
|
|
90
|
+
router,
|
|
91
|
+
});
|
|
92
|
+
out.print();
|
|
93
|
+
};
|
|
94
|
+
// =============================================================================
|
|
95
|
+
// Status App Subcommand
|
|
96
|
+
// =============================================================================
|
|
97
|
+
export const statusApp = async (argv) => {
|
|
98
|
+
const opts = {
|
|
99
|
+
string: ["org"],
|
|
100
|
+
boolean: ["help", "json"],
|
|
101
|
+
};
|
|
102
|
+
const args = parseArgs(argv, opts);
|
|
103
|
+
checkArgs(args, opts, "ambit status app");
|
|
104
|
+
if (args.help) {
|
|
105
|
+
console.log(`
|
|
106
|
+
${bold("ambit status app")} - Show App Status
|
|
107
|
+
|
|
108
|
+
${bold("USAGE")}
|
|
109
|
+
ambit status app <app>.<network> [--org <org>] [--json]
|
|
110
|
+
|
|
111
|
+
${bold("OPTIONS")}
|
|
112
|
+
--org <org> Fly.io organization slug
|
|
113
|
+
--json Output as JSON
|
|
114
|
+
|
|
115
|
+
${bold("EXAMPLES")}
|
|
116
|
+
ambit status app my-app.browsers
|
|
117
|
+
ambit status app my-app.browsers --json
|
|
118
|
+
`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const out = createOutput(args.json);
|
|
122
|
+
const appArg = args._[0];
|
|
123
|
+
if (!appArg || typeof appArg !== "string") {
|
|
124
|
+
return out.die("Missing App Name. Usage: ambit status app <app>.<network>");
|
|
125
|
+
}
|
|
126
|
+
if (!appArg.includes(".")) {
|
|
127
|
+
return out.die(`Missing Network. Use: ambit status app ${appArg}.<network>`);
|
|
128
|
+
}
|
|
129
|
+
const parts = appArg.split(".");
|
|
130
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
131
|
+
return out.die(`'${appArg}' Should Have Exactly One Dot, Like my-app.my-network`);
|
|
132
|
+
}
|
|
133
|
+
const app = parts[0];
|
|
134
|
+
const network = parts[1];
|
|
135
|
+
const prereqOut = createOutput(args.json);
|
|
136
|
+
const { fly, tailscale, org } = await initSession(prereqOut, {
|
|
137
|
+
json: args.json,
|
|
138
|
+
org: args.org,
|
|
139
|
+
});
|
|
140
|
+
await stageAppStatus(fly, tailscale, app, network, org, args.json);
|
|
141
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/status/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Status Command - Show Network, App, and Router Status
|
|
3
|
+
// =============================================================================
|
|
4
|
+
import { parseArgs } from "../../../deps/jsr.io/@std/cli/1.0.28/mod.js";
|
|
5
|
+
import { bold } from "../../../lib/cli.js";
|
|
6
|
+
import { registerCommand } from "../../mod.js";
|
|
7
|
+
import { statusNetworks } from "./networks.js";
|
|
8
|
+
import { statusNetwork } from "./network.js";
|
|
9
|
+
import { statusApp } from "./app.js";
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Top-Level Help
|
|
12
|
+
// =============================================================================
|
|
13
|
+
const showStatusHelp = () => {
|
|
14
|
+
console.log(`
|
|
15
|
+
${bold("ambit status")} - Show Network, App, and Router Status
|
|
16
|
+
|
|
17
|
+
${bold("USAGE")}
|
|
18
|
+
ambit status [options]
|
|
19
|
+
ambit status networks [options]
|
|
20
|
+
ambit status network <name> [options]
|
|
21
|
+
ambit status app <app>.<network> [options]
|
|
22
|
+
|
|
23
|
+
${bold("SUBCOMMANDS")}
|
|
24
|
+
networks Show summary of all networks — default when no subcommand given
|
|
25
|
+
network Show detailed status for a specific network
|
|
26
|
+
app Show a specific app's status
|
|
27
|
+
|
|
28
|
+
${bold("OPTIONS")}
|
|
29
|
+
--org <org> Fly.io organization slug
|
|
30
|
+
--json Output as JSON
|
|
31
|
+
|
|
32
|
+
${bold("EXAMPLES")}
|
|
33
|
+
ambit status
|
|
34
|
+
ambit status networks
|
|
35
|
+
ambit status network browsers
|
|
36
|
+
ambit status app my-app.browsers
|
|
37
|
+
|
|
38
|
+
Run 'ambit status networks --help', 'ambit status network --help',
|
|
39
|
+
or 'ambit status app --help' for details.
|
|
40
|
+
`);
|
|
41
|
+
};
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// Dispatcher
|
|
44
|
+
// =============================================================================
|
|
45
|
+
const status = async (argv) => {
|
|
46
|
+
const subcommand = typeof argv[0] === "string" ? argv[0] : undefined;
|
|
47
|
+
if (subcommand === "networks")
|
|
48
|
+
return statusNetworks(argv.slice(1));
|
|
49
|
+
if (subcommand === "network")
|
|
50
|
+
return statusNetwork(argv.slice(1));
|
|
51
|
+
if (subcommand === "app")
|
|
52
|
+
return statusApp(argv.slice(1));
|
|
53
|
+
const args = parseArgs(argv, { boolean: ["help"] });
|
|
54
|
+
if (args.help) {
|
|
55
|
+
showStatusHelp();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
return statusNetworks(argv);
|
|
59
|
+
};
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// Register Command
|
|
62
|
+
// =============================================================================
|
|
63
|
+
registerCommand({
|
|
64
|
+
name: "status",
|
|
65
|
+
description: "Show network, app, and router status",
|
|
66
|
+
usage: "ambit status [networks|network|app] [<name>] [--org <org>] [--json]",
|
|
67
|
+
run: status,
|
|
68
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/status/network.ts"],"names":[],"mappings":"AAgHA,eAAO,MAAM,aAAa,GAAU,MAAM,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CAsChE,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Status Network — Show Detailed Status for a Single Network
|
|
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 { findRouterApp, getRouterMachineInfo, getRouterTailscaleInfo, listWorkloadAppsOnNetwork, } from "../../../util/discovery.js";
|
|
9
|
+
import { initSession } from "../../../util/session.js";
|
|
10
|
+
import { SOCKS_PROXY_PORT } from "../../../util/constants.js";
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Detailed View
|
|
13
|
+
// =============================================================================
|
|
14
|
+
const stageNetworkStatus = async (fly, tailscale, network, org, json) => {
|
|
15
|
+
const out = createOutput(json);
|
|
16
|
+
const app = await findRouterApp(fly, org, network);
|
|
17
|
+
if (!app) {
|
|
18
|
+
return out.die(`No Router Found for Network '${network}'`);
|
|
19
|
+
}
|
|
20
|
+
const machine = await getRouterMachineInfo(fly, app.appName);
|
|
21
|
+
const ts = await getRouterTailscaleInfo(tailscale, app.appName);
|
|
22
|
+
const tag = ts?.tags?.[0] ?? null;
|
|
23
|
+
out.blank()
|
|
24
|
+
.header("Ambit Status: Network")
|
|
25
|
+
.blank()
|
|
26
|
+
.text(` Network: ${bold(app.network)}`)
|
|
27
|
+
.text(` TLD: *.${app.network}`)
|
|
28
|
+
.text(` Tag: ${tag ?? "unknown"}`)
|
|
29
|
+
.text(` Status: ${app.status}`)
|
|
30
|
+
.blank()
|
|
31
|
+
.text(` Router App: ${app.appName}`)
|
|
32
|
+
.text(` Region: ${machine?.region ?? "unknown"}`)
|
|
33
|
+
.text(` Machine State: ${machine?.state ?? "no machines"}`)
|
|
34
|
+
.text(` Private IP: ${machine?.privateIp ?? "unknown"}`)
|
|
35
|
+
.text(` SOCKS Proxy: ${machine?.privateIp
|
|
36
|
+
? `socks5://[${machine.privateIp}]:${SOCKS_PROXY_PORT}`
|
|
37
|
+
: "unknown"}`);
|
|
38
|
+
if (machine?.subnet) {
|
|
39
|
+
out.text(` Subnet: ${machine.subnet}`);
|
|
40
|
+
}
|
|
41
|
+
out.blank();
|
|
42
|
+
if (ts) {
|
|
43
|
+
out.text(` Tailscale IP: ${ts.ip}`)
|
|
44
|
+
.text(` Online: ${ts.online ? "yes" : "no"}`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
out.text(" Tailscale: Not Found in Tailnet");
|
|
48
|
+
}
|
|
49
|
+
// Show workload apps on this network
|
|
50
|
+
const workloads = await listWorkloadAppsOnNetwork(fly, org, network);
|
|
51
|
+
if (workloads.length > 0) {
|
|
52
|
+
out.blank().header(" Apps on Network").blank();
|
|
53
|
+
for (const w of workloads) {
|
|
54
|
+
const machines = await fly.machines.list(w.appName);
|
|
55
|
+
const state = machines[0]?.state ?? "no machines";
|
|
56
|
+
const region = machines[0]?.region ?? "-";
|
|
57
|
+
out.text(` ${w.appName} ${region} ${state}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
out.blank();
|
|
61
|
+
out.done({
|
|
62
|
+
network: app.network,
|
|
63
|
+
router: app,
|
|
64
|
+
machine,
|
|
65
|
+
tag,
|
|
66
|
+
tailscale: ts,
|
|
67
|
+
});
|
|
68
|
+
out.print();
|
|
69
|
+
};
|
|
70
|
+
// =============================================================================
|
|
71
|
+
// Status Network Subcommand
|
|
72
|
+
// =============================================================================
|
|
73
|
+
export const statusNetwork = async (argv) => {
|
|
74
|
+
const opts = { string: ["org"], boolean: ["help", "json"] };
|
|
75
|
+
const args = parseArgs(argv, opts);
|
|
76
|
+
checkArgs(args, opts, "ambit status network");
|
|
77
|
+
if (args.help) {
|
|
78
|
+
console.log(`
|
|
79
|
+
${bold("ambit status network")} - Show Detailed Status for a Network
|
|
80
|
+
|
|
81
|
+
${bold("USAGE")}
|
|
82
|
+
ambit status network <name> [--org <org>] [--json]
|
|
83
|
+
|
|
84
|
+
${bold("OPTIONS")}
|
|
85
|
+
--org <org> Fly.io organization slug
|
|
86
|
+
--json Output as JSON
|
|
87
|
+
|
|
88
|
+
${bold("EXAMPLES")}
|
|
89
|
+
ambit status network browsers
|
|
90
|
+
`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const out = createOutput(args.json);
|
|
94
|
+
const network = typeof args._[0] === "string" ? args._[0] : undefined;
|
|
95
|
+
if (!network) {
|
|
96
|
+
return out.die("Missing Network Name. Usage: ambit status network <name>");
|
|
97
|
+
}
|
|
98
|
+
const prereqOut = createOutput(args.json);
|
|
99
|
+
const { fly, tailscale, org } = await initSession(prereqOut, {
|
|
100
|
+
json: args.json,
|
|
101
|
+
org: args.org,
|
|
102
|
+
});
|
|
103
|
+
await stageNetworkStatus(fly, tailscale, network, org, args.json);
|
|
104
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"networks.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/status/networks.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,cAAc,GAAU,MAAM,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CAwDjE,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Status Networks — Summary Table of All Networks
|
|
3
|
+
// =============================================================================
|
|
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";
|
|
9
|
+
import { discoverRouters } from "../../../util/discovery.js";
|
|
10
|
+
import { initSession } from "../../../util/session.js";
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Status Networks Subcommand
|
|
13
|
+
// =============================================================================
|
|
14
|
+
export const statusNetworks = async (argv) => {
|
|
15
|
+
const opts = { string: ["org"], boolean: ["help", "json"] };
|
|
16
|
+
const args = parseArgs(argv, opts);
|
|
17
|
+
checkArgs(args, opts, "ambit status networks");
|
|
18
|
+
if (args.help) {
|
|
19
|
+
console.log(`
|
|
20
|
+
${bold("ambit status networks")} - Show Status of All Networks
|
|
21
|
+
|
|
22
|
+
${bold("USAGE")}
|
|
23
|
+
ambit status networks [--org <org>] [--json]
|
|
24
|
+
|
|
25
|
+
${bold("OPTIONS")}
|
|
26
|
+
--org <org> Fly.io organization slug
|
|
27
|
+
--json Output as JSON
|
|
28
|
+
`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const out = createOutput(args.json);
|
|
32
|
+
const { fly, tailscale, org } = await initSession(out, {
|
|
33
|
+
json: args.json,
|
|
34
|
+
org: args.org,
|
|
35
|
+
});
|
|
36
|
+
const routers = await discoverRouters(out, fly, tailscale, org);
|
|
37
|
+
if (routers.length === 0) {
|
|
38
|
+
out.blank()
|
|
39
|
+
.text("No Networks Found.")
|
|
40
|
+
.dim(" Create One with: ambit create <network>")
|
|
41
|
+
.blank();
|
|
42
|
+
out.done({ routers: [] });
|
|
43
|
+
out.print();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
out.blank().header("Network Status").blank();
|
|
47
|
+
const rows = routers.map((r) => {
|
|
48
|
+
const tsStatus = r.tailscale
|
|
49
|
+
? (r.tailscale.online ? "online" : "offline")
|
|
50
|
+
: "not found";
|
|
51
|
+
return [r.network, r.appName, r.status, tsStatus];
|
|
52
|
+
});
|
|
53
|
+
const table = new Table()
|
|
54
|
+
.header(["Network", "App", "Status", "Tailscale"])
|
|
55
|
+
.body(rows)
|
|
56
|
+
.indent(2)
|
|
57
|
+
.padding(2);
|
|
58
|
+
out.text(table.toString());
|
|
59
|
+
out.blank();
|
|
60
|
+
out.done({ routers });
|
|
61
|
+
out.print();
|
|
62
|
+
};
|
package/esm/deno.js
CHANGED
package/esm/main.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import "./_dnt.polyfills.js";
|
|
|
3
3
|
import "./cli/commands/create/index.js";
|
|
4
4
|
import "./cli/commands/deploy/index.js";
|
|
5
5
|
import "./cli/commands/share.js";
|
|
6
|
-
import "./cli/commands/list.js";
|
|
7
|
-
import "./cli/commands/status.js";
|
|
6
|
+
import "./cli/commands/list/index.js";
|
|
7
|
+
import "./cli/commands/status/index.js";
|
|
8
8
|
import "./cli/commands/destroy/index.js";
|
|
9
9
|
import "./cli/commands/doctor.js";
|
|
10
10
|
//# sourceMappingURL=main.d.ts.map
|
package/esm/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,OAAO,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,OAAO,qBAAqB,CAAC;AAkC7B,OAAO,gCAAgC,CAAC;AACxC,OAAO,gCAAgC,CAAC;AACxC,OAAO,yBAAyB,CAAC;AACjC,OAAO,8BAA8B,CAAC;AACtC,OAAO,gCAAgC,CAAC;AACxC,OAAO,iCAAiC,CAAC;AACzC,OAAO,0BAA0B,CAAC"}
|
package/esm/main.js
CHANGED
|
@@ -19,7 +19,10 @@ import * as dntShim from "./_dnt.shims.js";
|
|
|
19
19
|
//
|
|
20
20
|
// Examples:
|
|
21
21
|
// ambit create browsers
|
|
22
|
+
// ambit list networks
|
|
23
|
+
// ambit list apps browsers
|
|
22
24
|
// ambit status
|
|
25
|
+
// ambit status network browsers
|
|
23
26
|
// ambit destroy network browsers
|
|
24
27
|
// ambit destroy app my-app.browsers
|
|
25
28
|
// ambit doctor
|
|
@@ -30,8 +33,8 @@ import { Spinner, statusErr } from "./lib/cli.js";
|
|
|
30
33
|
import "./cli/commands/create/index.js";
|
|
31
34
|
import "./cli/commands/deploy/index.js";
|
|
32
35
|
import "./cli/commands/share.js";
|
|
33
|
-
import "./cli/commands/list.js";
|
|
34
|
-
import "./cli/commands/status.js";
|
|
36
|
+
import "./cli/commands/list/index.js";
|
|
37
|
+
import "./cli/commands/status/index.js";
|
|
35
38
|
import "./cli/commands/destroy/index.js";
|
|
36
39
|
import "./cli/commands/doctor.js";
|
|
37
40
|
// =============================================================================
|
package/esm/router/start.sh
CHANGED
|
@@ -5,7 +5,8 @@ set -e
|
|
|
5
5
|
# ambit - Self-Configuring Tailscale Subnet Router
|
|
6
6
|
# =============================================================================
|
|
7
7
|
# State is persisted to /var/lib/tailscale via Fly volume.
|
|
8
|
-
# On first run:
|
|
8
|
+
# On first run: waits for TAILSCALE_AUTHKEY (delivered by the CLI after
|
|
9
|
+
# autoApprovers are in place), then authenticates and advertises routes.
|
|
9
10
|
# On restart: reuses existing state, no new device created.
|
|
10
11
|
# The router never receives the user's API token — only a single-use,
|
|
11
12
|
# tag-scoped auth key that expires after 5 minutes.
|
|
@@ -41,10 +42,12 @@ if /usr/local/bin/tailscale status --json 2>/dev/null | jq -e '.BackendState ==
|
|
|
41
42
|
--hostname="${FLY_APP_NAME:-ambit}" \
|
|
42
43
|
--advertise-routes="${SUBNET}"
|
|
43
44
|
else
|
|
44
|
-
# First run
|
|
45
|
+
# First run — auth key is delivered by the CLI via `fly secrets set` after
|
|
46
|
+
# autoApprovers are configured. If it's not here yet, wait for the restart
|
|
47
|
+
# that the non-staged secrets set triggers.
|
|
45
48
|
if [ -z "${TAILSCALE_AUTHKEY}" ]; then
|
|
46
|
-
echo "Router:
|
|
47
|
-
|
|
49
|
+
echo "Router: Waiting for Auth Key (CLI will deliver via secrets)"
|
|
50
|
+
while true; do sleep 5; done
|
|
48
51
|
fi
|
|
49
52
|
|
|
50
53
|
echo "Router: Authenticating to Tailscale"
|
package/esm/schemas/fly.d.ts
CHANGED
|
@@ -3,6 +3,40 @@ export declare const FlyAuthSchema: z.ZodObject<{
|
|
|
3
3
|
email: z.ZodString;
|
|
4
4
|
}, z.core.$loose>;
|
|
5
5
|
export type FlyAuth = z.infer<typeof FlyAuthSchema>;
|
|
6
|
+
/** App-level status from the Fly GraphQL API / REST API (AppState enum). */
|
|
7
|
+
export declare const FlyAppStatusEnum: z.ZodEnum<{
|
|
8
|
+
deployed: "deployed";
|
|
9
|
+
pending: "pending";
|
|
10
|
+
suspended: "suspended";
|
|
11
|
+
}>;
|
|
12
|
+
export type FlyAppStatus = z.infer<typeof FlyAppStatusEnum>;
|
|
13
|
+
/**
|
|
14
|
+
* Machine-level state from the Fly Machines API.
|
|
15
|
+
* Persistent: created, started, stopped, suspended, failed
|
|
16
|
+
* Transient: creating, starting, stopping, restarting, suspending, destroying,
|
|
17
|
+
* updating, replacing, launch_failed
|
|
18
|
+
* Terminal: destroyed, replaced, migrated
|
|
19
|
+
*/
|
|
20
|
+
export declare const FlyMachineStateEnum: z.ZodEnum<{
|
|
21
|
+
suspended: "suspended";
|
|
22
|
+
created: "created";
|
|
23
|
+
started: "started";
|
|
24
|
+
stopped: "stopped";
|
|
25
|
+
failed: "failed";
|
|
26
|
+
creating: "creating";
|
|
27
|
+
starting: "starting";
|
|
28
|
+
stopping: "stopping";
|
|
29
|
+
restarting: "restarting";
|
|
30
|
+
suspending: "suspending";
|
|
31
|
+
destroying: "destroying";
|
|
32
|
+
updating: "updating";
|
|
33
|
+
replacing: "replacing";
|
|
34
|
+
launch_failed: "launch_failed";
|
|
35
|
+
destroyed: "destroyed";
|
|
36
|
+
replaced: "replaced";
|
|
37
|
+
migrated: "migrated";
|
|
38
|
+
}>;
|
|
39
|
+
export type FlyMachineState = z.infer<typeof FlyMachineStateEnum>;
|
|
6
40
|
export declare const FlyAppSchema: z.ZodObject<{
|
|
7
41
|
Name: z.ZodString;
|
|
8
42
|
Status: z.ZodString;
|
|
@@ -50,7 +84,25 @@ export declare const FlyMachineConfigSchema: z.ZodObject<{
|
|
|
50
84
|
export declare const FlyMachineSchema: z.ZodObject<{
|
|
51
85
|
id: z.ZodString;
|
|
52
86
|
name: z.ZodString;
|
|
53
|
-
state: z.
|
|
87
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
88
|
+
suspended: "suspended";
|
|
89
|
+
created: "created";
|
|
90
|
+
started: "started";
|
|
91
|
+
stopped: "stopped";
|
|
92
|
+
failed: "failed";
|
|
93
|
+
creating: "creating";
|
|
94
|
+
starting: "starting";
|
|
95
|
+
stopping: "stopping";
|
|
96
|
+
restarting: "restarting";
|
|
97
|
+
suspending: "suspending";
|
|
98
|
+
destroying: "destroying";
|
|
99
|
+
updating: "updating";
|
|
100
|
+
replacing: "replacing";
|
|
101
|
+
launch_failed: "launch_failed";
|
|
102
|
+
destroyed: "destroyed";
|
|
103
|
+
replaced: "replaced";
|
|
104
|
+
migrated: "migrated";
|
|
105
|
+
}>>;
|
|
54
106
|
region: z.ZodString;
|
|
55
107
|
private_ip: z.ZodOptional<z.ZodString>;
|
|
56
108
|
config: z.ZodOptional<z.ZodObject<{
|
|
@@ -77,7 +129,25 @@ export type FlyMachine = z.infer<typeof FlyMachineSchema>;
|
|
|
77
129
|
export declare const FlyMachinesListSchema: z.ZodArray<z.ZodObject<{
|
|
78
130
|
id: z.ZodString;
|
|
79
131
|
name: z.ZodString;
|
|
80
|
-
state: z.
|
|
132
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
133
|
+
suspended: "suspended";
|
|
134
|
+
created: "created";
|
|
135
|
+
started: "started";
|
|
136
|
+
stopped: "stopped";
|
|
137
|
+
failed: "failed";
|
|
138
|
+
creating: "creating";
|
|
139
|
+
starting: "starting";
|
|
140
|
+
stopping: "stopping";
|
|
141
|
+
restarting: "restarting";
|
|
142
|
+
suspending: "suspending";
|
|
143
|
+
destroying: "destroying";
|
|
144
|
+
updating: "updating";
|
|
145
|
+
replacing: "replacing";
|
|
146
|
+
launch_failed: "launch_failed";
|
|
147
|
+
destroyed: "destroyed";
|
|
148
|
+
replaced: "replaced";
|
|
149
|
+
migrated: "migrated";
|
|
150
|
+
}>>;
|
|
81
151
|
region: z.ZodString;
|
|
82
152
|
private_ip: z.ZodOptional<z.ZodString>;
|
|
83
153
|
config: z.ZodOptional<z.ZodObject<{
|
|
@@ -142,7 +212,12 @@ export declare const FlyIpListSchema: z.ZodArray<z.ZodObject<{
|
|
|
142
212
|
export declare const FlyAppInfoSchema: z.ZodObject<{
|
|
143
213
|
name: z.ZodString;
|
|
144
214
|
network: z.ZodString;
|
|
145
|
-
status: z.
|
|
215
|
+
status: z.ZodCatch<z.ZodEnum<{
|
|
216
|
+
deployed: "deployed";
|
|
217
|
+
pending: "pending";
|
|
218
|
+
suspended: "suspended";
|
|
219
|
+
}>>;
|
|
220
|
+
machine_count: z.ZodOptional<z.ZodNumber>;
|
|
146
221
|
organization: z.ZodOptional<z.ZodObject<{
|
|
147
222
|
slug: z.ZodString;
|
|
148
223
|
}, z.core.$strip>>;
|
|
@@ -153,7 +228,12 @@ export declare const FlyAppInfoListSchema: z.ZodObject<{
|
|
|
153
228
|
apps: z.ZodArray<z.ZodObject<{
|
|
154
229
|
name: z.ZodString;
|
|
155
230
|
network: z.ZodString;
|
|
156
|
-
status: z.
|
|
231
|
+
status: z.ZodCatch<z.ZodEnum<{
|
|
232
|
+
deployed: "deployed";
|
|
233
|
+
pending: "pending";
|
|
234
|
+
suspended: "suspended";
|
|
235
|
+
}>>;
|
|
236
|
+
machine_count: z.ZodOptional<z.ZodNumber>;
|
|
157
237
|
organization: z.ZodOptional<z.ZodObject<{
|
|
158
238
|
slug: z.ZodString;
|
|
159
239
|
}, z.core.$strip>>;
|
package/esm/schemas/fly.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fly.d.ts","sourceRoot":"","sources":["../../src/schemas/fly.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,4CAA4C,CAAC;AAM/D,eAAO,MAAM,aAAa;;iBAEhB,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAMpD,eAAO,MAAM,YAAY;;;;;;iBAMf,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,iBAAiB;;;;;;kBAAwB,CAAC;AAMvD,eAAO,MAAM,eAAe;;;;;iBAKlB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAMxD,eAAO,MAAM,qBAAqB;;;;iBAIxB,CAAC;AAEX,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;iBAgBzB,CAAC;AAEX,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"fly.d.ts","sourceRoot":"","sources":["../../src/schemas/fly.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,4CAA4C,CAAC;AAM/D,eAAO,MAAM,aAAa;;iBAEhB,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAMpD,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB;;;;EAA+C,CAAC;AAC7E,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;EAkB9B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMlE,eAAO,MAAM,YAAY;;;;;;iBAMf,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,iBAAiB;;;;;;kBAAwB,CAAC;AAMvD,eAAO,MAAM,eAAe;;;;;iBAKlB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAMxD,eAAO,MAAM,qBAAqB;;;;iBAIxB,CAAC;AAEX,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;iBAgBzB,CAAC;AAEX,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBASnB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAA4B,CAAC;AAM/D,eAAO,MAAM,aAAa,uCAAmC,CAAC;AAM9D,eAAO,MAAM,eAAe;;;iBAGlB,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAMpD,eAAO,MAAM,kBAAkB;;;;;iBAGrB,CAAC;AAEX,eAAO,MAAM,WAAW;;;;;;;;;;;;iBAOd,CAAC;AAEX,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEhD,eAAO,MAAM,eAAe;;;;;;;;;;;;kBAAuB,CAAC;AAMpD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;iBAMnB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;iBAGvB,CAAC"}
|
package/esm/schemas/fly.js
CHANGED
|
@@ -9,6 +9,37 @@ export const FlyAuthSchema = z.object({
|
|
|
9
9
|
email: z.string(),
|
|
10
10
|
}).loose();
|
|
11
11
|
// =============================================================================
|
|
12
|
+
// State Enums
|
|
13
|
+
// =============================================================================
|
|
14
|
+
/** App-level status from the Fly GraphQL API / REST API (AppState enum). */
|
|
15
|
+
export const FlyAppStatusEnum = z.enum(["deployed", "pending", "suspended"]);
|
|
16
|
+
/**
|
|
17
|
+
* Machine-level state from the Fly Machines API.
|
|
18
|
+
* Persistent: created, started, stopped, suspended, failed
|
|
19
|
+
* Transient: creating, starting, stopping, restarting, suspending, destroying,
|
|
20
|
+
* updating, replacing, launch_failed
|
|
21
|
+
* Terminal: destroyed, replaced, migrated
|
|
22
|
+
*/
|
|
23
|
+
export const FlyMachineStateEnum = z.enum([
|
|
24
|
+
"created",
|
|
25
|
+
"started",
|
|
26
|
+
"stopped",
|
|
27
|
+
"suspended",
|
|
28
|
+
"failed",
|
|
29
|
+
"creating",
|
|
30
|
+
"starting",
|
|
31
|
+
"stopping",
|
|
32
|
+
"restarting",
|
|
33
|
+
"suspending",
|
|
34
|
+
"destroying",
|
|
35
|
+
"updating",
|
|
36
|
+
"replacing",
|
|
37
|
+
"launch_failed",
|
|
38
|
+
"destroyed",
|
|
39
|
+
"replaced",
|
|
40
|
+
"migrated",
|
|
41
|
+
]);
|
|
42
|
+
// =============================================================================
|
|
12
43
|
// App Schemas
|
|
13
44
|
// =============================================================================
|
|
14
45
|
export const FlyAppSchema = z.object({
|
|
@@ -52,7 +83,7 @@ export const FlyMachineConfigSchema = z.object({
|
|
|
52
83
|
export const FlyMachineSchema = z.object({
|
|
53
84
|
id: z.string(),
|
|
54
85
|
name: z.string(),
|
|
55
|
-
state:
|
|
86
|
+
state: FlyMachineStateEnum.catch("created"),
|
|
56
87
|
region: z.string(),
|
|
57
88
|
private_ip: z.string().optional(),
|
|
58
89
|
config: FlyMachineConfigSchema.optional(),
|
|
@@ -93,7 +124,8 @@ export const FlyIpListSchema = z.array(FlyIpSchema);
|
|
|
93
124
|
export const FlyAppInfoSchema = z.object({
|
|
94
125
|
name: z.string(),
|
|
95
126
|
network: z.string(),
|
|
96
|
-
status:
|
|
127
|
+
status: FlyAppStatusEnum.catch("pending"),
|
|
128
|
+
machine_count: z.number().optional(),
|
|
97
129
|
organization: z.object({ slug: z.string() }).optional(),
|
|
98
130
|
}).loose();
|
|
99
131
|
export const FlyAppInfoListSchema = z.object({
|