@studiometa/forge-cli 0.4.4 → 0.4.6
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 +14 -0
- package/dist/cli.js +576 -34
- package/dist/cli.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/daemons/command.d.ts.map +1 -1
- package/dist/commands/daemons/handlers.d.ts +1 -0
- package/dist/commands/daemons/handlers.d.ts.map +1 -1
- package/dist/commands/daemons/help.d.ts.map +1 -1
- package/dist/commands/deployments/command.d.ts.map +1 -1
- package/dist/commands/deployments/handlers.d.ts +1 -0
- package/dist/commands/deployments/handlers.d.ts.map +1 -1
- package/dist/commands/deployments/help.d.ts.map +1 -1
- package/dist/commands/services/command.d.ts +2 -0
- package/dist/commands/services/command.d.ts.map +1 -0
- package/dist/commands/services/handlers.d.ts +10 -0
- package/dist/commands/services/handlers.d.ts.map +1 -0
- package/dist/commands/services/help.d.ts +2 -0
- package/dist/commands/services/help.d.ts.map +1 -0
- package/dist/commands/services/index.d.ts +3 -0
- package/dist/commands/services/index.d.ts.map +1 -0
- package/dist/commands/ssh/command.d.ts +9 -0
- package/dist/commands/ssh/command.d.ts.map +1 -0
- package/dist/commands/ssh/handlers.d.ts +16 -0
- package/dist/commands/ssh/handlers.d.ts.map +1 -0
- package/dist/commands/ssh/help.d.ts +2 -0
- package/dist/commands/ssh/help.d.ts.map +1 -0
- package/dist/commands/ssh/index.d.ts +3 -0
- package/dist/commands/ssh/index.d.ts.map +1 -0
- package/dist/commands/ssh/ssh-target.d.ts +36 -0
- package/dist/commands/ssh/ssh-target.d.ts.map +1 -0
- package/dist/{error-handler-ByMitiOr.js → error-handler-BA357jIr.js} +34 -3
- package/dist/error-handler-BA357jIr.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/output.d.ts +5 -4
- package/dist/output.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/error-handler-ByMitiOr.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { S as isOutputFormat, _ as ApiError, a as createContext, b as ValidationError, c as colors, d as deleteToken, g as setToken, h as setOrganizationSlug, i as runCommand, l as setColorEnabled, m as getToken, n as exitWithValidationError, p as getOrganizationSlug, s as OutputFormatter, u as createConfigStore } from "./error-handler-
|
|
3
|
-
import { activateCertificate, createAuditLogger, createBackupConfig, createCommand, createDatabaseUser, createMonitor, createNginxTemplate, createRedirectRule, createScheduledJob, createSecurityRule, deleteBackupConfig, deleteDatabaseUser, deleteMonitor, deleteNginxTemplate, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deploySiteAndWait, getBackupConfig, getCertificate, getCommand, getDaemon, getDatabase, getDatabaseUser, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listSites, listSshKeys, matchByName, rebootServer, restartDaemon, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateEnv, updateNginxConfig, updateNginxTemplate, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
|
|
2
|
+
import { S as isOutputFormat, _ as ApiError, a as createContext, b as ValidationError, c as colors, d as deleteToken, g as setToken, h as setOrganizationSlug, i as runCommand, l as setColorEnabled, m as getToken, n as exitWithValidationError, p as getOrganizationSlug, s as OutputFormatter, u as createConfigStore } from "./error-handler-BA357jIr.js";
|
|
3
|
+
import { RESTARTABLE_SERVICES, activateCertificate, createAuditLogger, createBackupConfig, createCommand, createDatabaseUser, createMonitor, createNginxTemplate, createRedirectRule, createScheduledJob, createSecurityRule, deleteBackupConfig, deleteDatabaseUser, deleteMonitor, deleteNginxTemplate, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deploySiteAndWait, getBackupConfig, getCertificate, getCommand, getDaemon, getDaemonLog, getDatabase, getDatabaseUser, getDeploymentLog, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listServices, listSites, listSshKeys, matchByName, rebootServer, restartDaemon, restartService, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateEnv, updateNginxConfig, updateNginxTemplate, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
|
|
4
4
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { join } from "node:path";
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
//#region src/audit.ts
|
|
7
9
|
/**
|
|
8
10
|
* Shared audit logger for CLI write operations.
|
|
9
11
|
* Lazily initialized on first use.
|
|
@@ -13,6 +15,8 @@ function getCliAuditLogger() {
|
|
|
13
15
|
if (!_auditLogger) _auditLogger = createAuditLogger("cli");
|
|
14
16
|
return _auditLogger;
|
|
15
17
|
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/utils/command-router.ts
|
|
16
20
|
/**
|
|
17
21
|
* Creates a command router function that dispatches to the appropriate handler.
|
|
18
22
|
*/
|
|
@@ -55,6 +59,8 @@ function createCommandRouter(config) {
|
|
|
55
59
|
else await handler(ctx);
|
|
56
60
|
};
|
|
57
61
|
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/utils/resolve.ts
|
|
58
64
|
/**
|
|
59
65
|
* Smart resolution utilities for --server and --site options.
|
|
60
66
|
*
|
|
@@ -106,6 +112,8 @@ async function resolveSiteId(value, serverId, execCtx) {
|
|
|
106
112
|
}
|
|
107
113
|
return String(partial[0].id);
|
|
108
114
|
}
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/commands/backups/handlers.ts
|
|
109
117
|
async function backupsList(ctx) {
|
|
110
118
|
const server = String(ctx.options.server ?? "");
|
|
111
119
|
if (!server) exitWithValidationError("server_id", "forge backups list --server <server_id>", ctx.formatter);
|
|
@@ -216,7 +224,9 @@ async function backupsDelete(args, ctx) {
|
|
|
216
224
|
ctx.formatter.success(`Backup configuration ${id} deleted.`);
|
|
217
225
|
}, ctx.formatter);
|
|
218
226
|
}
|
|
219
|
-
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/commands/backups/command.ts
|
|
229
|
+
var handleBackupsCommand = createCommandRouter({
|
|
220
230
|
resource: "backups",
|
|
221
231
|
handlers: {
|
|
222
232
|
list: backupsList,
|
|
@@ -232,6 +242,8 @@ const handleBackupsCommand = createCommandRouter({
|
|
|
232
242
|
"delete"
|
|
233
243
|
]
|
|
234
244
|
});
|
|
245
|
+
//#endregion
|
|
246
|
+
//#region src/commands/backups/help.ts
|
|
235
247
|
function showBackupsHelp(subcommand) {
|
|
236
248
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
237
249
|
${colors.bold("forge backups list")} - List backup configurations on a server
|
|
@@ -309,6 +321,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
309
321
|
Run ${colors.cyan("forge backups <subcommand> --help")} for details.
|
|
310
322
|
`);
|
|
311
323
|
}
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/commands/completion.ts
|
|
312
326
|
/**
|
|
313
327
|
* Shell completion installation command
|
|
314
328
|
*/
|
|
@@ -322,16 +336,16 @@ _forge_completions() {
|
|
|
322
336
|
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
323
337
|
|
|
324
338
|
# Main commands
|
|
325
|
-
commands="config servers s sites deployments d databases db database-users daemons env nginx certificates certs firewall-rules fw ssh-keys backups commands scheduled-jobs user monitors nginx-templates security-rules redirect-rules recipes completion help"
|
|
339
|
+
commands="config servers s sites deployments d databases db database-users daemons env nginx certificates certs firewall-rules fw ssh ssh-keys backups commands scheduled-jobs services user monitors nginx-templates security-rules redirect-rules recipes completion help"
|
|
326
340
|
|
|
327
341
|
# Subcommands for each command
|
|
328
342
|
local config_cmds="set get delete"
|
|
329
343
|
local servers_cmds="list ls get reboot"
|
|
330
344
|
local sites_cmds="list ls get"
|
|
331
|
-
local deployments_cmds="list ls deploy"
|
|
345
|
+
local deployments_cmds="list ls deploy logs log"
|
|
332
346
|
local databases_cmds="list ls get"
|
|
333
347
|
local database_users_cmds="list ls get create delete"
|
|
334
|
-
local daemons_cmds="list ls get restart"
|
|
348
|
+
local daemons_cmds="list ls get restart logs log"
|
|
335
349
|
local env_cmds="get update"
|
|
336
350
|
local nginx_cmds="get update"
|
|
337
351
|
local certificates_cmds="get activate"
|
|
@@ -340,6 +354,7 @@ _forge_completions() {
|
|
|
340
354
|
local backups_cmds="list ls get create delete"
|
|
341
355
|
local commands_cmds="list ls get create"
|
|
342
356
|
local scheduled_jobs_cmds="list ls get create delete"
|
|
357
|
+
local services_cmds="list ls restart"
|
|
343
358
|
local user_cmds="get"
|
|
344
359
|
local monitors_cmds="list ls get create delete"
|
|
345
360
|
local nginx_templates_cmds="list ls get create update delete"
|
|
@@ -349,7 +364,7 @@ _forge_completions() {
|
|
|
349
364
|
local completion_cmds="bash zsh fish"
|
|
350
365
|
|
|
351
366
|
# Global options
|
|
352
|
-
options="--token --server --site -f --format --no-color -h --help -v --version --name --command --content --from --to --provider --frequency --type --operator --threshold --minutes --key --port --ip-address --user --script --servers --domain --password --credential-id --region --size --project-type --directory"
|
|
367
|
+
options="--token --server --site -f --format --no-color -h --help -v --version --name --command --content --from --to --provider --frequency --type --operator --threshold --minutes --key --port --ip-address --user --private --dry-run --script --servers --domain --password --credential-id --region --size --project-type --directory"
|
|
353
368
|
|
|
354
369
|
# Format options
|
|
355
370
|
local formats="json human table"
|
|
@@ -408,6 +423,9 @@ _forge_completions() {
|
|
|
408
423
|
scheduled-jobs)
|
|
409
424
|
COMPREPLY=( $(compgen -W "\${scheduled_jobs_cmds}" -- "\${cur}") )
|
|
410
425
|
;;
|
|
426
|
+
services)
|
|
427
|
+
COMPREPLY=( $(compgen -W "\${services_cmds}" -- "\${cur}") )
|
|
428
|
+
;;
|
|
411
429
|
user)
|
|
412
430
|
COMPREPLY=( $(compgen -W "\${user_cmds}" -- "\${cur}") )
|
|
413
431
|
;;
|
|
@@ -486,10 +504,12 @@ _forge() {
|
|
|
486
504
|
'certs:Manage SSL certificates (alias)'
|
|
487
505
|
'firewall-rules:Manage firewall rules'
|
|
488
506
|
'fw:Manage firewall rules (alias)'
|
|
507
|
+
'ssh:Open an SSH session to a server'
|
|
489
508
|
'ssh-keys:Manage SSH keys'
|
|
490
509
|
'backups:Manage backup configurations'
|
|
491
510
|
'commands:Manage site commands'
|
|
492
511
|
'scheduled-jobs:Manage scheduled jobs'
|
|
512
|
+
'services:List and restart server services'
|
|
493
513
|
'user:Display authenticated user profile'
|
|
494
514
|
'monitors:Manage server monitors'
|
|
495
515
|
'nginx-templates:Manage Nginx templates'
|
|
@@ -537,6 +557,8 @@ _forge() {
|
|
|
537
557
|
'list:List deployments'
|
|
538
558
|
'ls:List deployments (alias)'
|
|
539
559
|
'deploy:Trigger a deployment'
|
|
560
|
+
'logs:Show deployment output'
|
|
561
|
+
'log:Show deployment output (alias)'
|
|
540
562
|
)
|
|
541
563
|
_describe 'deployments command' deployments_cmds
|
|
542
564
|
;;
|
|
@@ -567,6 +589,8 @@ _forge() {
|
|
|
567
589
|
'ls:List daemons (alias)'
|
|
568
590
|
'get:Get daemon details'
|
|
569
591
|
'restart:Restart a daemon'
|
|
592
|
+
'logs:Show daemon log output'
|
|
593
|
+
'log:Show daemon log output (alias)'
|
|
570
594
|
)
|
|
571
595
|
_describe 'daemons command' daemons_cmds
|
|
572
596
|
;;
|
|
@@ -644,6 +668,15 @@ _forge() {
|
|
|
644
668
|
)
|
|
645
669
|
_describe 'scheduled-jobs command' scheduled_jobs_cmds
|
|
646
670
|
;;
|
|
671
|
+
services)
|
|
672
|
+
local -a services_cmds
|
|
673
|
+
services_cmds=(
|
|
674
|
+
'list:List services on a server'
|
|
675
|
+
'ls:List services on a server (alias)'
|
|
676
|
+
'restart:Restart a service'
|
|
677
|
+
)
|
|
678
|
+
_describe 'services command' services_cmds
|
|
679
|
+
;;
|
|
647
680
|
user)
|
|
648
681
|
local -a user_cmds
|
|
649
682
|
user_cmds=(
|
|
@@ -775,10 +808,12 @@ complete -c forge -f -n "__fish_use_subcommand" -a "certificates" -d "Manage SSL
|
|
|
775
808
|
complete -c forge -f -n "__fish_use_subcommand" -a "certs" -d "Manage SSL certificates (alias)"
|
|
776
809
|
complete -c forge -f -n "__fish_use_subcommand" -a "firewall-rules" -d "Manage firewall rules"
|
|
777
810
|
complete -c forge -f -n "__fish_use_subcommand" -a "fw" -d "Manage firewall rules (alias)"
|
|
811
|
+
complete -c forge -f -n "__fish_use_subcommand" -a "ssh" -d "Open an SSH session to a server"
|
|
778
812
|
complete -c forge -f -n "__fish_use_subcommand" -a "ssh-keys" -d "Manage SSH keys"
|
|
779
813
|
complete -c forge -f -n "__fish_use_subcommand" -a "backups" -d "Manage backup configurations"
|
|
780
814
|
complete -c forge -f -n "__fish_use_subcommand" -a "commands" -d "Manage site commands"
|
|
781
815
|
complete -c forge -f -n "__fish_use_subcommand" -a "scheduled-jobs" -d "Manage scheduled jobs"
|
|
816
|
+
complete -c forge -f -n "__fish_use_subcommand" -a "services" -d "List and restart server services"
|
|
782
817
|
complete -c forge -f -n "__fish_use_subcommand" -a "user" -d "Display authenticated user profile"
|
|
783
818
|
complete -c forge -f -n "__fish_use_subcommand" -a "monitors" -d "Manage server monitors"
|
|
784
819
|
complete -c forge -f -n "__fish_use_subcommand" -a "nginx-templates" -d "Manage Nginx templates"
|
|
@@ -808,6 +843,8 @@ complete -c forge -f -n "__fish_seen_subcommand_from sites" -a "get" -d "Get sit
|
|
|
808
843
|
complete -c forge -f -n "__fish_seen_subcommand_from deployments d" -a "list" -d "List deployments"
|
|
809
844
|
complete -c forge -f -n "__fish_seen_subcommand_from deployments d" -a "ls" -d "List deployments (alias)"
|
|
810
845
|
complete -c forge -f -n "__fish_seen_subcommand_from deployments d" -a "deploy" -d "Trigger a deployment"
|
|
846
|
+
complete -c forge -f -n "__fish_seen_subcommand_from deployments d" -a "logs" -d "Show deployment output"
|
|
847
|
+
complete -c forge -f -n "__fish_seen_subcommand_from deployments d" -a "log" -d "Show deployment output (alias)"
|
|
811
848
|
|
|
812
849
|
# databases subcommands
|
|
813
850
|
complete -c forge -f -n "__fish_seen_subcommand_from databases db" -a "list" -d "List databases"
|
|
@@ -826,6 +863,8 @@ complete -c forge -f -n "__fish_seen_subcommand_from daemons" -a "list" -d "List
|
|
|
826
863
|
complete -c forge -f -n "__fish_seen_subcommand_from daemons" -a "ls" -d "List daemons (alias)"
|
|
827
864
|
complete -c forge -f -n "__fish_seen_subcommand_from daemons" -a "get" -d "Get daemon details"
|
|
828
865
|
complete -c forge -f -n "__fish_seen_subcommand_from daemons" -a "restart" -d "Restart a daemon"
|
|
866
|
+
complete -c forge -f -n "__fish_seen_subcommand_from daemons" -a "logs" -d "Show daemon log output"
|
|
867
|
+
complete -c forge -f -n "__fish_seen_subcommand_from daemons" -a "log" -d "Show daemon log output (alias)"
|
|
829
868
|
|
|
830
869
|
# env subcommands
|
|
831
870
|
complete -c forge -f -n "__fish_seen_subcommand_from env" -a "get" -d "Get env variables"
|
|
@@ -870,6 +909,11 @@ complete -c forge -f -n "__fish_seen_subcommand_from scheduled-jobs" -a "get" -d
|
|
|
870
909
|
complete -c forge -f -n "__fish_seen_subcommand_from scheduled-jobs" -a "create" -d "Create a scheduled job"
|
|
871
910
|
complete -c forge -f -n "__fish_seen_subcommand_from scheduled-jobs" -a "delete" -d "Delete a scheduled job"
|
|
872
911
|
|
|
912
|
+
# services subcommands
|
|
913
|
+
complete -c forge -f -n "__fish_seen_subcommand_from services" -a "list" -d "List services on a server"
|
|
914
|
+
complete -c forge -f -n "__fish_seen_subcommand_from services" -a "ls" -d "List services on a server (alias)"
|
|
915
|
+
complete -c forge -f -n "__fish_seen_subcommand_from services" -a "restart" -d "Restart a service"
|
|
916
|
+
|
|
873
917
|
# user subcommands
|
|
874
918
|
complete -c forge -f -n "__fish_seen_subcommand_from user" -a "get" -d "Get the authenticated user profile"
|
|
875
919
|
|
|
@@ -1053,6 +1097,8 @@ function handleCompletionCommand(shell, options = {}) {
|
|
|
1053
1097
|
process.exit(1);
|
|
1054
1098
|
}
|
|
1055
1099
|
}
|
|
1100
|
+
//#endregion
|
|
1101
|
+
//#region src/commands/certificates/handlers.ts
|
|
1056
1102
|
function requireServerSiteDomainRaw(ctx, usage) {
|
|
1057
1103
|
const server = String(ctx.options.server ?? "");
|
|
1058
1104
|
const site = String(ctx.options.site ?? "");
|
|
@@ -1104,7 +1150,9 @@ async function certificatesActivate(args, ctx) {
|
|
|
1104
1150
|
ctx.formatter.success(`Certificate for domain ${domainId} activated.`);
|
|
1105
1151
|
}, ctx.formatter);
|
|
1106
1152
|
}
|
|
1107
|
-
|
|
1153
|
+
//#endregion
|
|
1154
|
+
//#region src/commands/certificates/command.ts
|
|
1155
|
+
var handleCertificatesCommand = createCommandRouter({
|
|
1108
1156
|
resource: "certificates",
|
|
1109
1157
|
handlers: {
|
|
1110
1158
|
get: [certificatesGet, "args"],
|
|
@@ -1112,6 +1160,8 @@ const handleCertificatesCommand = createCommandRouter({
|
|
|
1112
1160
|
},
|
|
1113
1161
|
writeSubcommands: ["activate"]
|
|
1114
1162
|
});
|
|
1163
|
+
//#endregion
|
|
1164
|
+
//#region src/commands/certificates/help.ts
|
|
1115
1165
|
function showCertificatesHelp(subcommand) {
|
|
1116
1166
|
if (subcommand === "get") console.log(`
|
|
1117
1167
|
${colors.bold("forge certificates get")} - Get certificate for a domain
|
|
@@ -1150,6 +1200,8 @@ ${colors.bold("NOTE:")}
|
|
|
1150
1200
|
Run ${colors.cyan("forge certificates <subcommand> --help")} for details.
|
|
1151
1201
|
`);
|
|
1152
1202
|
}
|
|
1203
|
+
//#endregion
|
|
1204
|
+
//#region src/commands/commands/handlers.ts
|
|
1153
1205
|
function requireServerAndSiteRaw$2(ctx, usage) {
|
|
1154
1206
|
const server = String(ctx.options.server ?? "");
|
|
1155
1207
|
const site = String(ctx.options.site ?? "");
|
|
@@ -1219,7 +1271,9 @@ async function commandsCreate(ctx) {
|
|
|
1219
1271
|
ctx.formatter.success("Command queued for execution.");
|
|
1220
1272
|
}, ctx.formatter);
|
|
1221
1273
|
}
|
|
1222
|
-
|
|
1274
|
+
//#endregion
|
|
1275
|
+
//#region src/commands/commands/command.ts
|
|
1276
|
+
var handleCommandsCommand = createCommandRouter({
|
|
1223
1277
|
resource: "commands",
|
|
1224
1278
|
handlers: {
|
|
1225
1279
|
list: commandsList,
|
|
@@ -1229,6 +1283,8 @@ const handleCommandsCommand = createCommandRouter({
|
|
|
1229
1283
|
},
|
|
1230
1284
|
writeSubcommands: ["create"]
|
|
1231
1285
|
});
|
|
1286
|
+
//#endregion
|
|
1287
|
+
//#region src/commands/commands/help.ts
|
|
1232
1288
|
function showCommandsHelp(subcommand) {
|
|
1233
1289
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
1234
1290
|
${colors.bold("forge commands list")} - List commands executed on a site
|
|
@@ -1278,6 +1334,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
1278
1334
|
Run ${colors.cyan("forge commands <subcommand> --help")} for details.
|
|
1279
1335
|
`);
|
|
1280
1336
|
}
|
|
1337
|
+
//#endregion
|
|
1338
|
+
//#region src/commands/config.ts
|
|
1281
1339
|
/**
|
|
1282
1340
|
* Config command — manage forge configuration
|
|
1283
1341
|
*/
|
|
@@ -1362,6 +1420,8 @@ function handleConfigCommand(subcommand, args, options) {
|
|
|
1362
1420
|
function maskToken(token) {
|
|
1363
1421
|
return token.length > 8 ? `${token.slice(0, 4)}${"*".repeat(token.length - 8)}${token.slice(-4)}` : "****";
|
|
1364
1422
|
}
|
|
1423
|
+
//#endregion
|
|
1424
|
+
//#region src/commands/daemons/handlers.ts
|
|
1365
1425
|
async function daemonsList(ctx) {
|
|
1366
1426
|
const server = String(ctx.options.server ?? "");
|
|
1367
1427
|
if (!server) exitWithValidationError("server_id", "forge daemons list --server <server_id>", ctx.formatter);
|
|
@@ -1400,6 +1460,22 @@ async function daemonsGet(args, ctx) {
|
|
|
1400
1460
|
]);
|
|
1401
1461
|
}, ctx.formatter);
|
|
1402
1462
|
}
|
|
1463
|
+
async function daemonsLogs(args, ctx) {
|
|
1464
|
+
const [id] = args;
|
|
1465
|
+
const server = String(ctx.options.server ?? "");
|
|
1466
|
+
if (!id) exitWithValidationError("daemon_id", "forge daemons logs <daemon_id> --server <server_id>", ctx.formatter);
|
|
1467
|
+
if (!server) exitWithValidationError("server_id", "forge daemons logs <daemon_id> --server <server_id>", ctx.formatter);
|
|
1468
|
+
await runCommand(async () => {
|
|
1469
|
+
const token = ctx.getToken();
|
|
1470
|
+
const execCtx = ctx.createExecutorContext(token);
|
|
1471
|
+
const result = await getDaemonLog({
|
|
1472
|
+
server_id: await resolveServerId(server, execCtx),
|
|
1473
|
+
id
|
|
1474
|
+
}, execCtx);
|
|
1475
|
+
if (result.data) ctx.formatter.outputText(result.data);
|
|
1476
|
+
else ctx.formatter.info("No log output available.");
|
|
1477
|
+
}, ctx.formatter);
|
|
1478
|
+
}
|
|
1403
1479
|
async function daemonsUpdate(args, ctx) {
|
|
1404
1480
|
const [id] = args;
|
|
1405
1481
|
const server = String(ctx.options.server ?? "");
|
|
@@ -1443,17 +1519,23 @@ async function daemonsRestart(args, ctx) {
|
|
|
1443
1519
|
ctx.formatter.success(`Daemon ${id} restarted.`);
|
|
1444
1520
|
}, ctx.formatter);
|
|
1445
1521
|
}
|
|
1446
|
-
|
|
1522
|
+
//#endregion
|
|
1523
|
+
//#region src/commands/daemons/command.ts
|
|
1524
|
+
var handleDaemonsCommand = createCommandRouter({
|
|
1447
1525
|
resource: "daemons",
|
|
1448
1526
|
handlers: {
|
|
1449
1527
|
list: daemonsList,
|
|
1450
1528
|
ls: daemonsList,
|
|
1451
1529
|
get: [daemonsGet, "args"],
|
|
1530
|
+
logs: [daemonsLogs, "args"],
|
|
1531
|
+
log: [daemonsLogs, "args"],
|
|
1452
1532
|
restart: [daemonsRestart, "args"],
|
|
1453
1533
|
update: [daemonsUpdate, "args"]
|
|
1454
1534
|
},
|
|
1455
1535
|
writeSubcommands: ["restart", "update"]
|
|
1456
1536
|
});
|
|
1537
|
+
//#endregion
|
|
1538
|
+
//#region src/commands/daemons/help.ts
|
|
1457
1539
|
function showDaemonsHelp(subcommand) {
|
|
1458
1540
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
1459
1541
|
${colors.bold("forge daemons list")} - List daemons on a server
|
|
@@ -1466,6 +1548,12 @@ ${colors.bold("forge daemons get")} - Get daemon details
|
|
|
1466
1548
|
|
|
1467
1549
|
${colors.bold("USAGE:")}
|
|
1468
1550
|
forge daemons get <daemon_id> --server <server_id>
|
|
1551
|
+
`);
|
|
1552
|
+
else if (subcommand === "logs" || subcommand === "log") console.log(`
|
|
1553
|
+
${colors.bold("forge daemons logs")} - Show the log output of a daemon
|
|
1554
|
+
|
|
1555
|
+
${colors.bold("USAGE:")}
|
|
1556
|
+
forge daemons logs <daemon_id> --server <server_id>
|
|
1469
1557
|
`);
|
|
1470
1558
|
else if (subcommand === "update") console.log(`
|
|
1471
1559
|
${colors.bold("forge daemons update")} - Update a daemon
|
|
@@ -1488,6 +1576,7 @@ ${colors.bold("USAGE:")}
|
|
|
1488
1576
|
${colors.bold("SUBCOMMANDS:")}
|
|
1489
1577
|
list, ls List daemons
|
|
1490
1578
|
get <id> Get daemon details
|
|
1579
|
+
logs <id> Show the log output of a daemon
|
|
1491
1580
|
update <id> Update a daemon
|
|
1492
1581
|
restart <id> Restart a daemon
|
|
1493
1582
|
|
|
@@ -1498,6 +1587,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
1498
1587
|
Run ${colors.cyan("forge daemons <subcommand> --help")} for details.
|
|
1499
1588
|
`);
|
|
1500
1589
|
}
|
|
1590
|
+
//#endregion
|
|
1591
|
+
//#region src/commands/databases/handlers.ts
|
|
1501
1592
|
async function databasesList(ctx) {
|
|
1502
1593
|
const server = String(ctx.options.server ?? "");
|
|
1503
1594
|
if (!server) exitWithValidationError("server_id", "forge databases list --server <server_id>", ctx.formatter);
|
|
@@ -1532,7 +1623,9 @@ async function databasesGet(args, ctx) {
|
|
|
1532
1623
|
]);
|
|
1533
1624
|
}, ctx.formatter);
|
|
1534
1625
|
}
|
|
1535
|
-
|
|
1626
|
+
//#endregion
|
|
1627
|
+
//#region src/commands/databases/command.ts
|
|
1628
|
+
var handleDatabasesCommand = createCommandRouter({
|
|
1536
1629
|
resource: "databases",
|
|
1537
1630
|
handlers: {
|
|
1538
1631
|
list: databasesList,
|
|
@@ -1540,6 +1633,8 @@ const handleDatabasesCommand = createCommandRouter({
|
|
|
1540
1633
|
get: [databasesGet, "args"]
|
|
1541
1634
|
}
|
|
1542
1635
|
});
|
|
1636
|
+
//#endregion
|
|
1637
|
+
//#region src/commands/databases/help.ts
|
|
1543
1638
|
function showDatabasesHelp(subcommand) {
|
|
1544
1639
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
1545
1640
|
${colors.bold("forge databases list")} - List databases on a server
|
|
@@ -1577,6 +1672,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
1577
1672
|
Run ${colors.cyan("forge databases <subcommand> --help")} for details.
|
|
1578
1673
|
`);
|
|
1579
1674
|
}
|
|
1675
|
+
//#endregion
|
|
1676
|
+
//#region src/commands/database-users/handlers.ts
|
|
1580
1677
|
async function databaseUsersList(ctx) {
|
|
1581
1678
|
const server = String(ctx.options.server ?? "");
|
|
1582
1679
|
if (!server) exitWithValidationError("server_id", "forge database-users list --server <server_id>", ctx.formatter);
|
|
@@ -1677,7 +1774,9 @@ async function databaseUsersDelete(args, ctx) {
|
|
|
1677
1774
|
ctx.formatter.success(`Database user ${id} deleted.`);
|
|
1678
1775
|
}, ctx.formatter);
|
|
1679
1776
|
}
|
|
1680
|
-
|
|
1777
|
+
//#endregion
|
|
1778
|
+
//#region src/commands/database-users/command.ts
|
|
1779
|
+
var handleDatabaseUsersCommand = createCommandRouter({
|
|
1681
1780
|
resource: "database-users",
|
|
1682
1781
|
handlers: {
|
|
1683
1782
|
list: databaseUsersList,
|
|
@@ -1693,6 +1792,8 @@ const handleDatabaseUsersCommand = createCommandRouter({
|
|
|
1693
1792
|
"delete"
|
|
1694
1793
|
]
|
|
1695
1794
|
});
|
|
1795
|
+
//#endregion
|
|
1796
|
+
//#region src/commands/database-users/help.ts
|
|
1696
1797
|
function showDatabaseUsersHelp(subcommand) {
|
|
1697
1798
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
1698
1799
|
${colors.bold("forge database-users list")} - List database users on a server
|
|
@@ -1761,6 +1862,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
1761
1862
|
Run ${colors.cyan("forge database-users <subcommand> --help")} for details.
|
|
1762
1863
|
`);
|
|
1763
1864
|
}
|
|
1865
|
+
//#endregion
|
|
1866
|
+
//#region src/commands/deployments/handlers.ts
|
|
1764
1867
|
async function deploymentsList(ctx) {
|
|
1765
1868
|
const server = String(ctx.options.server ?? "");
|
|
1766
1869
|
const site = String(ctx.options.site ?? "");
|
|
@@ -1782,6 +1885,38 @@ async function deploymentsList(ctx) {
|
|
|
1782
1885
|
], "No deployments found.", (d) => `${String(d.id).padEnd(8)} ${d.status.padEnd(12)} ${(d.commit.hash ?? "—").padEnd(10)} ${d.started_at}`);
|
|
1783
1886
|
}, ctx.formatter);
|
|
1784
1887
|
}
|
|
1888
|
+
async function deploymentsLogs(args, ctx) {
|
|
1889
|
+
const [deploymentId] = args;
|
|
1890
|
+
const server = String(ctx.options.server ?? "");
|
|
1891
|
+
const site = String(ctx.options.site ?? "");
|
|
1892
|
+
if (!server) exitWithValidationError("server_id", "forge deployments logs [deployment_id] --server <server_id> --site <site_id>", ctx.formatter);
|
|
1893
|
+
if (!site) exitWithValidationError("site_id", "forge deployments logs [deployment_id] --server <server_id> --site <site_id>", ctx.formatter);
|
|
1894
|
+
await runCommand(async () => {
|
|
1895
|
+
const token = ctx.getToken();
|
|
1896
|
+
const execCtx = ctx.createExecutorContext(token);
|
|
1897
|
+
const server_id = await resolveServerId(server, execCtx);
|
|
1898
|
+
const site_id = await resolveSiteId(site, server_id, execCtx);
|
|
1899
|
+
let deployment_id = deploymentId;
|
|
1900
|
+
if (!deployment_id) {
|
|
1901
|
+
const deployments = await listDeployments({
|
|
1902
|
+
server_id,
|
|
1903
|
+
site_id
|
|
1904
|
+
}, execCtx);
|
|
1905
|
+
if (deployments.data.length === 0) {
|
|
1906
|
+
ctx.formatter.info("No deployments found.");
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
deployment_id = String(deployments.data[0].id);
|
|
1910
|
+
}
|
|
1911
|
+
const result = await getDeploymentLog({
|
|
1912
|
+
server_id,
|
|
1913
|
+
site_id,
|
|
1914
|
+
deployment_id
|
|
1915
|
+
}, execCtx);
|
|
1916
|
+
if (result.data) ctx.formatter.outputText(result.data);
|
|
1917
|
+
else ctx.formatter.info("No log output available.");
|
|
1918
|
+
}, ctx.formatter);
|
|
1919
|
+
}
|
|
1785
1920
|
async function deploymentsDeploy(ctx) {
|
|
1786
1921
|
const server = String(ctx.options.server ?? "");
|
|
1787
1922
|
const site = String(ctx.options.site ?? "");
|
|
@@ -1811,15 +1946,21 @@ async function deploymentsDeploy(ctx) {
|
|
|
1811
1946
|
else throw new ApiError(`Deployment failed for site ${site_id} (${elapsedSec}s).`);
|
|
1812
1947
|
}, ctx.formatter);
|
|
1813
1948
|
}
|
|
1814
|
-
|
|
1949
|
+
//#endregion
|
|
1950
|
+
//#region src/commands/deployments/command.ts
|
|
1951
|
+
var handleDeploymentsCommand = createCommandRouter({
|
|
1815
1952
|
resource: "deployments",
|
|
1816
1953
|
handlers: {
|
|
1817
1954
|
list: deploymentsList,
|
|
1818
1955
|
ls: deploymentsList,
|
|
1819
|
-
deploy: deploymentsDeploy
|
|
1956
|
+
deploy: deploymentsDeploy,
|
|
1957
|
+
logs: [deploymentsLogs, "args"],
|
|
1958
|
+
log: [deploymentsLogs, "args"]
|
|
1820
1959
|
},
|
|
1821
1960
|
writeSubcommands: ["deploy"]
|
|
1822
1961
|
});
|
|
1962
|
+
//#endregion
|
|
1963
|
+
//#region src/commands/deployments/help.ts
|
|
1823
1964
|
function showDeploymentsHelp(subcommand) {
|
|
1824
1965
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
1825
1966
|
${colors.bold("forge deployments list")} - List deployments for a site
|
|
@@ -1827,6 +1968,17 @@ ${colors.bold("forge deployments list")} - List deployments for a site
|
|
|
1827
1968
|
${colors.bold("USAGE:")}
|
|
1828
1969
|
forge deployments list --server <server_id> --site <site_id> [options]
|
|
1829
1970
|
|
|
1971
|
+
${colors.bold("OPTIONS:")}
|
|
1972
|
+
--server <id> Server ID (required)
|
|
1973
|
+
--site <id> Site ID (required)
|
|
1974
|
+
-f, --format <fmt> Output format: json, human, table
|
|
1975
|
+
`);
|
|
1976
|
+
else if (subcommand === "logs" || subcommand === "log") console.log(`
|
|
1977
|
+
${colors.bold("forge deployments logs")} - Show output of a deployment (latest if no id)
|
|
1978
|
+
|
|
1979
|
+
${colors.bold("USAGE:")}
|
|
1980
|
+
forge deployments logs [deployment_id] --server <server_id> --site <site_id>
|
|
1981
|
+
|
|
1830
1982
|
${colors.bold("OPTIONS:")}
|
|
1831
1983
|
--server <id> Server ID (required)
|
|
1832
1984
|
--site <id> Site ID (required)
|
|
@@ -1856,6 +2008,7 @@ ${colors.bold("ALIASES:")}
|
|
|
1856
2008
|
${colors.bold("SUBCOMMANDS:")}
|
|
1857
2009
|
list, ls List deployments for a site
|
|
1858
2010
|
deploy Trigger a deployment
|
|
2011
|
+
logs Show output of a deployment (latest if no id)
|
|
1859
2012
|
|
|
1860
2013
|
${colors.bold("OPTIONS:")}
|
|
1861
2014
|
--server <id> Server ID (required)
|
|
@@ -1865,6 +2018,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
1865
2018
|
Run ${colors.cyan("forge deployments <subcommand> --help")} for details.
|
|
1866
2019
|
`);
|
|
1867
2020
|
}
|
|
2021
|
+
//#endregion
|
|
2022
|
+
//#region src/commands/env/handlers.ts
|
|
1868
2023
|
async function envGet(ctx) {
|
|
1869
2024
|
const server = String(ctx.options.server ?? "");
|
|
1870
2025
|
const site = String(ctx.options.site ?? "");
|
|
@@ -1901,7 +2056,9 @@ async function envUpdate(ctx) {
|
|
|
1901
2056
|
ctx.formatter.success("Environment variables updated.");
|
|
1902
2057
|
}, ctx.formatter);
|
|
1903
2058
|
}
|
|
1904
|
-
|
|
2059
|
+
//#endregion
|
|
2060
|
+
//#region src/commands/env/command.ts
|
|
2061
|
+
var handleEnvCommand = createCommandRouter({
|
|
1905
2062
|
resource: "env",
|
|
1906
2063
|
handlers: {
|
|
1907
2064
|
get: envGet,
|
|
@@ -1909,6 +2066,8 @@ const handleEnvCommand = createCommandRouter({
|
|
|
1909
2066
|
},
|
|
1910
2067
|
writeSubcommands: ["update"]
|
|
1911
2068
|
});
|
|
2069
|
+
//#endregion
|
|
2070
|
+
//#region src/commands/env/help.ts
|
|
1912
2071
|
function showEnvHelp(subcommand) {
|
|
1913
2072
|
if (subcommand === "get") console.log(`
|
|
1914
2073
|
${colors.bold("forge env get")} - Get environment variables
|
|
@@ -1941,6 +2100,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
1941
2100
|
Run ${colors.cyan("forge env <subcommand> --help")} for details.
|
|
1942
2101
|
`);
|
|
1943
2102
|
}
|
|
2103
|
+
//#endregion
|
|
2104
|
+
//#region src/commands/firewall-rules/handlers.ts
|
|
1944
2105
|
async function firewallRulesList(ctx) {
|
|
1945
2106
|
const server = String(ctx.options.server ?? "");
|
|
1946
2107
|
if (!server) exitWithValidationError("server_id", "forge firewall-rules list --server <server_id>", ctx.formatter);
|
|
@@ -1981,7 +2142,9 @@ async function firewallRulesGet(args, ctx) {
|
|
|
1981
2142
|
]);
|
|
1982
2143
|
}, ctx.formatter);
|
|
1983
2144
|
}
|
|
1984
|
-
|
|
2145
|
+
//#endregion
|
|
2146
|
+
//#region src/commands/firewall-rules/command.ts
|
|
2147
|
+
var handleFirewallRulesCommand = createCommandRouter({
|
|
1985
2148
|
resource: "firewall-rules",
|
|
1986
2149
|
handlers: {
|
|
1987
2150
|
list: firewallRulesList,
|
|
@@ -1989,6 +2152,8 @@ const handleFirewallRulesCommand = createCommandRouter({
|
|
|
1989
2152
|
get: [firewallRulesGet, "args"]
|
|
1990
2153
|
}
|
|
1991
2154
|
});
|
|
2155
|
+
//#endregion
|
|
2156
|
+
//#region src/commands/firewall-rules/help.ts
|
|
1992
2157
|
function showFirewallRulesHelp(subcommand) {
|
|
1993
2158
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
1994
2159
|
${colors.bold("forge firewall-rules list")} - List firewall rules on a server
|
|
@@ -2022,6 +2187,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
2022
2187
|
Run ${colors.cyan("forge firewall-rules <subcommand> --help")} for details.
|
|
2023
2188
|
`);
|
|
2024
2189
|
}
|
|
2190
|
+
//#endregion
|
|
2191
|
+
//#region src/commands/monitors/handlers.ts
|
|
2025
2192
|
async function monitorsList(ctx) {
|
|
2026
2193
|
const server = String(ctx.options.server ?? "");
|
|
2027
2194
|
if (!server) exitWithValidationError("server_id", "forge monitors list --server <server_id>", ctx.formatter);
|
|
@@ -2107,7 +2274,9 @@ async function monitorsDelete(args, ctx) {
|
|
|
2107
2274
|
ctx.formatter.success(`Monitor ${id} deleted.`);
|
|
2108
2275
|
}, ctx.formatter);
|
|
2109
2276
|
}
|
|
2110
|
-
|
|
2277
|
+
//#endregion
|
|
2278
|
+
//#region src/commands/monitors/command.ts
|
|
2279
|
+
var handleMonitorsCommand = createCommandRouter({
|
|
2111
2280
|
resource: "monitors",
|
|
2112
2281
|
handlers: {
|
|
2113
2282
|
list: monitorsList,
|
|
@@ -2118,6 +2287,8 @@ const handleMonitorsCommand = createCommandRouter({
|
|
|
2118
2287
|
},
|
|
2119
2288
|
writeSubcommands: ["create", "delete"]
|
|
2120
2289
|
});
|
|
2290
|
+
//#endregion
|
|
2291
|
+
//#region src/commands/monitors/help.ts
|
|
2121
2292
|
function showMonitorsHelp(subcommand) {
|
|
2122
2293
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
2123
2294
|
${colors.bold("forge monitors list")} - List monitors on a server
|
|
@@ -2174,6 +2345,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
2174
2345
|
Run ${colors.cyan("forge monitors <subcommand> --help")} for details.
|
|
2175
2346
|
`);
|
|
2176
2347
|
}
|
|
2348
|
+
//#endregion
|
|
2349
|
+
//#region src/commands/nginx/handlers.ts
|
|
2177
2350
|
async function nginxGet(ctx) {
|
|
2178
2351
|
const server = String(ctx.options.server ?? "");
|
|
2179
2352
|
const site = String(ctx.options.site ?? "");
|
|
@@ -2210,7 +2383,9 @@ async function nginxUpdate(ctx) {
|
|
|
2210
2383
|
ctx.formatter.success("Nginx configuration updated.");
|
|
2211
2384
|
}, ctx.formatter);
|
|
2212
2385
|
}
|
|
2213
|
-
|
|
2386
|
+
//#endregion
|
|
2387
|
+
//#region src/commands/nginx/command.ts
|
|
2388
|
+
var handleNginxCommand = createCommandRouter({
|
|
2214
2389
|
resource: "nginx",
|
|
2215
2390
|
handlers: {
|
|
2216
2391
|
get: nginxGet,
|
|
@@ -2218,6 +2393,8 @@ const handleNginxCommand = createCommandRouter({
|
|
|
2218
2393
|
},
|
|
2219
2394
|
writeSubcommands: ["update"]
|
|
2220
2395
|
});
|
|
2396
|
+
//#endregion
|
|
2397
|
+
//#region src/commands/nginx/help.ts
|
|
2221
2398
|
function showNginxHelp(subcommand) {
|
|
2222
2399
|
if (subcommand === "get") console.log(`
|
|
2223
2400
|
${colors.bold("forge nginx get")} - Get nginx configuration
|
|
@@ -2249,6 +2426,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
2249
2426
|
Run ${colors.cyan("forge nginx <subcommand> --help")} for details.
|
|
2250
2427
|
`);
|
|
2251
2428
|
}
|
|
2429
|
+
//#endregion
|
|
2430
|
+
//#region src/commands/nginx-templates/handlers.ts
|
|
2252
2431
|
async function nginxTemplatesList(ctx) {
|
|
2253
2432
|
const server = String(ctx.options.server ?? "");
|
|
2254
2433
|
if (!server) exitWithValidationError("server_id", "forge nginx-templates list --server <server_id>", ctx.formatter);
|
|
@@ -2313,11 +2492,14 @@ async function nginxTemplatesUpdate(args, ctx) {
|
|
|
2313
2492
|
await runCommand(async () => {
|
|
2314
2493
|
const token = ctx.getToken();
|
|
2315
2494
|
const execCtx = ctx.createExecutorContext(token);
|
|
2495
|
+
const server_id = await resolveServerId(server, execCtx);
|
|
2496
|
+
const name = ctx.options.name ? String(ctx.options.name) : void 0;
|
|
2497
|
+
const content = ctx.options.content ? String(ctx.options.content) : void 0;
|
|
2316
2498
|
const result = await updateNginxTemplate({
|
|
2317
|
-
server_id
|
|
2499
|
+
server_id,
|
|
2318
2500
|
id,
|
|
2319
|
-
name
|
|
2320
|
-
content
|
|
2501
|
+
name,
|
|
2502
|
+
content
|
|
2321
2503
|
}, execCtx);
|
|
2322
2504
|
ctx.formatter.outputOne(result.data, [
|
|
2323
2505
|
"id",
|
|
@@ -2341,7 +2523,9 @@ async function nginxTemplatesDelete(args, ctx) {
|
|
|
2341
2523
|
ctx.formatter.success(`Nginx template ${id} deleted.`);
|
|
2342
2524
|
}, ctx.formatter);
|
|
2343
2525
|
}
|
|
2344
|
-
|
|
2526
|
+
//#endregion
|
|
2527
|
+
//#region src/commands/nginx-templates/command.ts
|
|
2528
|
+
var handleNginxTemplatesCommand = createCommandRouter({
|
|
2345
2529
|
resource: "nginx-templates",
|
|
2346
2530
|
handlers: {
|
|
2347
2531
|
list: nginxTemplatesList,
|
|
@@ -2357,6 +2541,8 @@ const handleNginxTemplatesCommand = createCommandRouter({
|
|
|
2357
2541
|
"delete"
|
|
2358
2542
|
]
|
|
2359
2543
|
});
|
|
2544
|
+
//#endregion
|
|
2545
|
+
//#region src/commands/nginx-templates/help.ts
|
|
2360
2546
|
function showNginxTemplatesHelp(subcommand) {
|
|
2361
2547
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
2362
2548
|
${colors.bold("forge nginx-templates list")} - List Nginx templates on a server
|
|
@@ -2424,6 +2610,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
2424
2610
|
Run ${colors.cyan("forge nginx-templates <subcommand> --help")} for details.
|
|
2425
2611
|
`);
|
|
2426
2612
|
}
|
|
2613
|
+
//#endregion
|
|
2614
|
+
//#region src/commands/recipes/handlers.ts
|
|
2427
2615
|
async function recipesList(ctx) {
|
|
2428
2616
|
await runCommand(async () => {
|
|
2429
2617
|
const token = ctx.getToken();
|
|
@@ -2492,7 +2680,9 @@ async function recipesRun(args, ctx) {
|
|
|
2492
2680
|
ctx.formatter.success(`Recipe ${id} dispatched to ${servers.length} server(s).`);
|
|
2493
2681
|
}, ctx.formatter);
|
|
2494
2682
|
}
|
|
2495
|
-
|
|
2683
|
+
//#endregion
|
|
2684
|
+
//#region src/commands/recipes/command.ts
|
|
2685
|
+
var handleRecipesCommand = createCommandRouter({
|
|
2496
2686
|
resource: "recipes",
|
|
2497
2687
|
handlers: {
|
|
2498
2688
|
list: recipesList,
|
|
@@ -2503,6 +2693,8 @@ const handleRecipesCommand = createCommandRouter({
|
|
|
2503
2693
|
},
|
|
2504
2694
|
writeSubcommands: ["update", "run"]
|
|
2505
2695
|
});
|
|
2696
|
+
//#endregion
|
|
2697
|
+
//#region src/commands/recipes/help.ts
|
|
2506
2698
|
function showRecipesHelp(subcommand) {
|
|
2507
2699
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
2508
2700
|
${colors.bold("forge recipes list")} - List all recipes
|
|
@@ -2554,6 +2746,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
2554
2746
|
Run ${colors.cyan("forge recipes <subcommand> --help")} for details.
|
|
2555
2747
|
`);
|
|
2556
2748
|
}
|
|
2749
|
+
//#endregion
|
|
2750
|
+
//#region src/commands/redirect-rules/handlers.ts
|
|
2557
2751
|
function requireServerAndSiteRaw$1(ctx, usage) {
|
|
2558
2752
|
const server = String(ctx.options.server ?? "");
|
|
2559
2753
|
const site = String(ctx.options.site ?? "");
|
|
@@ -2644,7 +2838,9 @@ async function redirectRulesDelete(args, ctx) {
|
|
|
2644
2838
|
ctx.formatter.success(`Redirect rule ${id} deleted.`);
|
|
2645
2839
|
}, ctx.formatter);
|
|
2646
2840
|
}
|
|
2647
|
-
|
|
2841
|
+
//#endregion
|
|
2842
|
+
//#region src/commands/redirect-rules/command.ts
|
|
2843
|
+
var handleRedirectRulesCommand = createCommandRouter({
|
|
2648
2844
|
resource: "redirect-rules",
|
|
2649
2845
|
handlers: {
|
|
2650
2846
|
list: redirectRulesList,
|
|
@@ -2655,6 +2851,8 @@ const handleRedirectRulesCommand = createCommandRouter({
|
|
|
2655
2851
|
},
|
|
2656
2852
|
writeSubcommands: ["create", "delete"]
|
|
2657
2853
|
});
|
|
2854
|
+
//#endregion
|
|
2855
|
+
//#region src/commands/redirect-rules/help.ts
|
|
2658
2856
|
function showRedirectRulesHelp(subcommand) {
|
|
2659
2857
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
2660
2858
|
${colors.bold("forge redirect-rules list")} - List redirect rules for a site
|
|
@@ -2712,6 +2910,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
2712
2910
|
Run ${colors.cyan("forge redirect-rules <subcommand> --help")} for details.
|
|
2713
2911
|
`);
|
|
2714
2912
|
}
|
|
2913
|
+
//#endregion
|
|
2914
|
+
//#region src/commands/scheduled-jobs/handlers.ts
|
|
2715
2915
|
async function scheduledJobsList(ctx) {
|
|
2716
2916
|
const server = String(ctx.options.server ?? "");
|
|
2717
2917
|
const site = ctx.options.site ? String(ctx.options.site) : void 0;
|
|
@@ -2742,10 +2942,11 @@ async function scheduledJobsGet(args, ctx) {
|
|
|
2742
2942
|
const token = ctx.getToken();
|
|
2743
2943
|
const execCtx = ctx.createExecutorContext(token);
|
|
2744
2944
|
const server_id = await resolveServerId(server, execCtx);
|
|
2945
|
+
const site_id = site ? await resolveSiteId(site, server_id, execCtx) : void 0;
|
|
2745
2946
|
const result = await getScheduledJob({
|
|
2746
2947
|
server_id,
|
|
2747
2948
|
id,
|
|
2748
|
-
site_id
|
|
2949
|
+
site_id
|
|
2749
2950
|
}, execCtx);
|
|
2750
2951
|
ctx.formatter.outputOne(result.data, [
|
|
2751
2952
|
"id",
|
|
@@ -2800,15 +3001,18 @@ async function scheduledJobsDelete(args, ctx) {
|
|
|
2800
3001
|
const token = ctx.getToken();
|
|
2801
3002
|
const execCtx = ctx.createExecutorContext(token);
|
|
2802
3003
|
const server_id = await resolveServerId(server, execCtx);
|
|
3004
|
+
const site_id = site ? await resolveSiteId(site, server_id, execCtx) : void 0;
|
|
2803
3005
|
await deleteScheduledJob({
|
|
2804
3006
|
server_id,
|
|
2805
3007
|
id,
|
|
2806
|
-
site_id
|
|
3008
|
+
site_id
|
|
2807
3009
|
}, execCtx);
|
|
2808
3010
|
ctx.formatter.success(`Scheduled job ${id} deleted.`);
|
|
2809
3011
|
}, ctx.formatter);
|
|
2810
3012
|
}
|
|
2811
|
-
|
|
3013
|
+
//#endregion
|
|
3014
|
+
//#region src/commands/scheduled-jobs/command.ts
|
|
3015
|
+
var handleScheduledJobsCommand = createCommandRouter({
|
|
2812
3016
|
resource: "scheduled-jobs",
|
|
2813
3017
|
handlers: {
|
|
2814
3018
|
list: scheduledJobsList,
|
|
@@ -2819,6 +3023,8 @@ const handleScheduledJobsCommand = createCommandRouter({
|
|
|
2819
3023
|
},
|
|
2820
3024
|
writeSubcommands: ["create", "delete"]
|
|
2821
3025
|
});
|
|
3026
|
+
//#endregion
|
|
3027
|
+
//#region src/commands/scheduled-jobs/help.ts
|
|
2822
3028
|
function showScheduledJobsHelp(subcommand) {
|
|
2823
3029
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
2824
3030
|
${colors.bold("forge scheduled-jobs list")} - List scheduled jobs on a server
|
|
@@ -2872,6 +3078,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
2872
3078
|
Run ${colors.cyan("forge scheduled-jobs <subcommand> --help")} for details.
|
|
2873
3079
|
`);
|
|
2874
3080
|
}
|
|
3081
|
+
//#endregion
|
|
3082
|
+
//#region src/commands/security-rules/handlers.ts
|
|
2875
3083
|
function requireServerAndSiteRaw(ctx, usage) {
|
|
2876
3084
|
const server = String(ctx.options.server ?? "");
|
|
2877
3085
|
const site = String(ctx.options.site ?? "");
|
|
@@ -2987,7 +3195,9 @@ async function securityRulesDelete(args, ctx) {
|
|
|
2987
3195
|
ctx.formatter.success(`Security rule ${id} deleted.`);
|
|
2988
3196
|
}, ctx.formatter);
|
|
2989
3197
|
}
|
|
2990
|
-
|
|
3198
|
+
//#endregion
|
|
3199
|
+
//#region src/commands/security-rules/command.ts
|
|
3200
|
+
var handleSecurityRulesCommand = createCommandRouter({
|
|
2991
3201
|
resource: "security-rules",
|
|
2992
3202
|
handlers: {
|
|
2993
3203
|
list: securityRulesList,
|
|
@@ -3003,6 +3213,8 @@ const handleSecurityRulesCommand = createCommandRouter({
|
|
|
3003
3213
|
"delete"
|
|
3004
3214
|
]
|
|
3005
3215
|
});
|
|
3216
|
+
//#endregion
|
|
3217
|
+
//#region src/commands/security-rules/help.ts
|
|
3006
3218
|
function showSecurityRulesHelp(subcommand) {
|
|
3007
3219
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
3008
3220
|
${colors.bold("forge security-rules list")} - List security rules for a site
|
|
@@ -3072,6 +3284,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
3072
3284
|
Run ${colors.cyan("forge security-rules <subcommand> --help")} for details.
|
|
3073
3285
|
`);
|
|
3074
3286
|
}
|
|
3287
|
+
//#endregion
|
|
3288
|
+
//#region src/commands/servers/handlers.ts
|
|
3075
3289
|
/**
|
|
3076
3290
|
* CLI handlers for servers commands.
|
|
3077
3291
|
* Delegates all HTTP logic to forge-core executors.
|
|
@@ -3121,7 +3335,9 @@ async function serversReboot(args, ctx) {
|
|
|
3121
3335
|
ctx.formatter.success(`Server ${server_id} reboot initiated.`);
|
|
3122
3336
|
}, ctx.formatter);
|
|
3123
3337
|
}
|
|
3124
|
-
|
|
3338
|
+
//#endregion
|
|
3339
|
+
//#region src/commands/servers/command.ts
|
|
3340
|
+
var handleServersCommand = createCommandRouter({
|
|
3125
3341
|
resource: "servers",
|
|
3126
3342
|
handlers: {
|
|
3127
3343
|
list: serversList,
|
|
@@ -3131,6 +3347,8 @@ const handleServersCommand = createCommandRouter({
|
|
|
3131
3347
|
},
|
|
3132
3348
|
writeSubcommands: ["reboot"]
|
|
3133
3349
|
});
|
|
3350
|
+
//#endregion
|
|
3351
|
+
//#region src/commands/servers/help.ts
|
|
3134
3352
|
function showServersHelp(subcommand) {
|
|
3135
3353
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
3136
3354
|
${colors.bold("forge servers list")} - List all servers
|
|
@@ -3201,6 +3419,124 @@ ${colors.bold("EXAMPLES:")}
|
|
|
3201
3419
|
Run ${colors.cyan("forge servers <subcommand> --help")} for subcommand details.
|
|
3202
3420
|
`);
|
|
3203
3421
|
}
|
|
3422
|
+
//#endregion
|
|
3423
|
+
//#region src/commands/services/handlers.ts
|
|
3424
|
+
/**
|
|
3425
|
+
* List services on a server with a derived availability flag.
|
|
3426
|
+
*/
|
|
3427
|
+
async function servicesList(args, ctx) {
|
|
3428
|
+
const [server] = args;
|
|
3429
|
+
if (!server) exitWithValidationError("server", "forge services list <server>", ctx.formatter);
|
|
3430
|
+
await runCommand(async () => {
|
|
3431
|
+
const token = ctx.getToken();
|
|
3432
|
+
const execCtx = ctx.createExecutorContext(token);
|
|
3433
|
+
const result = await listServices({ server_id: await resolveServerId(server, execCtx) }, execCtx);
|
|
3434
|
+
ctx.formatter.outputList(result.data, [
|
|
3435
|
+
"service",
|
|
3436
|
+
"available",
|
|
3437
|
+
"detail"
|
|
3438
|
+
], "No services.", (row) => {
|
|
3439
|
+
const status = row.available ? "yes" : "no";
|
|
3440
|
+
const detail = row.detail ? ` (${row.detail})` : "";
|
|
3441
|
+
return `${row.service.padEnd(12)}${status}${detail}`;
|
|
3442
|
+
});
|
|
3443
|
+
}, ctx.formatter);
|
|
3444
|
+
}
|
|
3445
|
+
/**
|
|
3446
|
+
* Restart a service on a server.
|
|
3447
|
+
*/
|
|
3448
|
+
async function servicesRestart(args, ctx) {
|
|
3449
|
+
const [server, service] = args;
|
|
3450
|
+
if (!server) exitWithValidationError("server", "forge services restart <server> <service>", ctx.formatter);
|
|
3451
|
+
if (!service) exitWithValidationError("service", "forge services restart <server> <service>", ctx.formatter);
|
|
3452
|
+
const version = ctx.options.version ? String(ctx.options.version) : void 0;
|
|
3453
|
+
await runCommand(async () => {
|
|
3454
|
+
if (!RESTARTABLE_SERVICES.includes(service)) throw new ValidationError(`Invalid service "${service}"`, "service", [`Valid services: ${RESTARTABLE_SERVICES.join(", ")}`]);
|
|
3455
|
+
const token = ctx.getToken();
|
|
3456
|
+
const execCtx = ctx.createExecutorContext(token);
|
|
3457
|
+
const server_id = await resolveServerId(server, execCtx);
|
|
3458
|
+
let resolvedVersion = version;
|
|
3459
|
+
if (service === "php" && !resolvedVersion) {
|
|
3460
|
+
const { data: srv } = await getServer({ server_id }, execCtx);
|
|
3461
|
+
if (!srv.php_version) throw new ValidationError("The php service requires a version", "version", ["Pass --version <php_version> (e.g. --version php83)"]);
|
|
3462
|
+
resolvedVersion = srv.php_version;
|
|
3463
|
+
}
|
|
3464
|
+
await restartService({
|
|
3465
|
+
server_id,
|
|
3466
|
+
service,
|
|
3467
|
+
version: resolvedVersion
|
|
3468
|
+
}, execCtx);
|
|
3469
|
+
ctx.formatter.success(`${service} restart initiated on server ${server_id}.`);
|
|
3470
|
+
}, ctx.formatter);
|
|
3471
|
+
}
|
|
3472
|
+
//#endregion
|
|
3473
|
+
//#region src/commands/services/command.ts
|
|
3474
|
+
var handleServicesCommand = createCommandRouter({
|
|
3475
|
+
resource: "services",
|
|
3476
|
+
handlers: {
|
|
3477
|
+
list: [servicesList, "args"],
|
|
3478
|
+
ls: [servicesList, "args"],
|
|
3479
|
+
restart: [servicesRestart, "args"]
|
|
3480
|
+
},
|
|
3481
|
+
writeSubcommands: ["restart"]
|
|
3482
|
+
});
|
|
3483
|
+
//#endregion
|
|
3484
|
+
//#region src/commands/services/help.ts
|
|
3485
|
+
function showServicesHelp(subcommand) {
|
|
3486
|
+
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
3487
|
+
${colors.bold("forge services list")} - List services on a server
|
|
3488
|
+
|
|
3489
|
+
${colors.bold("USAGE:")}
|
|
3490
|
+
forge services list <server> [options]
|
|
3491
|
+
|
|
3492
|
+
${colors.bold("ARGUMENTS:")}
|
|
3493
|
+
<server> Server ID or name (required)
|
|
3494
|
+
|
|
3495
|
+
${colors.bold("NOTES:")}
|
|
3496
|
+
Availability is a heuristic derived from the server object — the API has
|
|
3497
|
+
no services listing endpoint.
|
|
3498
|
+
|
|
3499
|
+
${colors.bold("EXAMPLES:")}
|
|
3500
|
+
forge services list 123
|
|
3501
|
+
forge services list my-server --format json
|
|
3502
|
+
`);
|
|
3503
|
+
else if (subcommand === "restart") console.log(`
|
|
3504
|
+
${colors.bold("forge services restart")} - Restart a service on a server
|
|
3505
|
+
|
|
3506
|
+
${colors.bold("USAGE:")}
|
|
3507
|
+
forge services restart <server> <service> [options]
|
|
3508
|
+
|
|
3509
|
+
${colors.bold("ARGUMENTS:")}
|
|
3510
|
+
<server> Server ID or name (required)
|
|
3511
|
+
<service> One of: nginx, php, mysql, postgres, redis, supervisor
|
|
3512
|
+
|
|
3513
|
+
${colors.bold("OPTIONS:")}
|
|
3514
|
+
--version <ver> PHP version (e.g. php83) — required for the php service
|
|
3515
|
+
(defaults to the server's php_version when omitted)
|
|
3516
|
+
|
|
3517
|
+
${colors.bold("EXAMPLES:")}
|
|
3518
|
+
forge services restart 123 nginx
|
|
3519
|
+
forge services restart 123 php --version php83
|
|
3520
|
+
`);
|
|
3521
|
+
else console.log(`
|
|
3522
|
+
${colors.bold("forge services")} - List and restart server services
|
|
3523
|
+
|
|
3524
|
+
${colors.bold("USAGE:")}
|
|
3525
|
+
forge services <subcommand> [options]
|
|
3526
|
+
|
|
3527
|
+
${colors.bold("SUBCOMMANDS:")}
|
|
3528
|
+
list, ls List services on a server
|
|
3529
|
+
restart <service> Restart a service (nginx, php, mysql, postgres, redis, supervisor)
|
|
3530
|
+
|
|
3531
|
+
${colors.bold("OPTIONS:")}
|
|
3532
|
+
--version <ver> PHP version (for the php service)
|
|
3533
|
+
-f, --format <fmt> Output format: json, human, table
|
|
3534
|
+
|
|
3535
|
+
Run ${colors.cyan("forge services <subcommand> --help")} for details.
|
|
3536
|
+
`);
|
|
3537
|
+
}
|
|
3538
|
+
//#endregion
|
|
3539
|
+
//#region src/commands/sites/handlers.ts
|
|
3204
3540
|
async function sitesList(ctx) {
|
|
3205
3541
|
const server = String(ctx.options.server ?? "");
|
|
3206
3542
|
if (!server) exitWithValidationError("server_id", "forge sites list --server <server_id>", ctx.formatter);
|
|
@@ -3276,7 +3612,9 @@ async function sitesUpdate(args, ctx) {
|
|
|
3276
3612
|
]);
|
|
3277
3613
|
}, ctx.formatter);
|
|
3278
3614
|
}
|
|
3279
|
-
|
|
3615
|
+
//#endregion
|
|
3616
|
+
//#region src/commands/sites/command.ts
|
|
3617
|
+
var handleSitesCommand = createCommandRouter({
|
|
3280
3618
|
resource: "sites",
|
|
3281
3619
|
handlers: {
|
|
3282
3620
|
list: sitesList,
|
|
@@ -3285,6 +3623,8 @@ const handleSitesCommand = createCommandRouter({
|
|
|
3285
3623
|
update: [sitesUpdate, "args"]
|
|
3286
3624
|
}
|
|
3287
3625
|
});
|
|
3626
|
+
//#endregion
|
|
3627
|
+
//#region src/commands/sites/help.ts
|
|
3288
3628
|
function showSitesHelp(subcommand) {
|
|
3289
3629
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
3290
3630
|
${colors.bold("forge sites list")} - List sites on a server
|
|
@@ -3335,6 +3675,172 @@ ${colors.bold("EXAMPLES:")}
|
|
|
3335
3675
|
Run ${colors.cyan("forge sites <subcommand> --help")} for subcommand details.
|
|
3336
3676
|
`);
|
|
3337
3677
|
}
|
|
3678
|
+
/**
|
|
3679
|
+
* Resolve the concrete user/host/port to connect to.
|
|
3680
|
+
*
|
|
3681
|
+
* @throws {ValidationError} when the selected IP is not available yet, or the port override is invalid.
|
|
3682
|
+
*/
|
|
3683
|
+
function resolveSshTarget(server, options = {}) {
|
|
3684
|
+
const user = options.user?.trim() || "forge";
|
|
3685
|
+
const host = options.private ? server.private_ip_address : server.ip_address;
|
|
3686
|
+
if (!host) {
|
|
3687
|
+
const which = options.private ? "private IP address" : "IP address";
|
|
3688
|
+
const hints = [server.is_ready ? "The server is ready but no address is available — check the Forge dashboard." : "The server is still provisioning. Wait until it is ready, then try again.", options.private ? void 0 : "Use --private to connect over the private network."].filter((hint) => Boolean(hint));
|
|
3689
|
+
throw new ValidationError(`Server "${server.name}" has no ${which} available`, "server", hints);
|
|
3690
|
+
}
|
|
3691
|
+
let port = server.ssh_port;
|
|
3692
|
+
if (options.port !== void 0) {
|
|
3693
|
+
const parsed = Number(options.port);
|
|
3694
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) throw new ValidationError(`Invalid SSH port "${options.port}"`, "port", ["Port must be an integer between 1 and 65535."]);
|
|
3695
|
+
port = parsed;
|
|
3696
|
+
}
|
|
3697
|
+
return {
|
|
3698
|
+
user,
|
|
3699
|
+
host,
|
|
3700
|
+
port
|
|
3701
|
+
};
|
|
3702
|
+
}
|
|
3703
|
+
/**
|
|
3704
|
+
* Build the argument list passed to the `ssh` binary.
|
|
3705
|
+
*
|
|
3706
|
+
* Any {@link remoteCommand} is appended after the connection flags, so
|
|
3707
|
+
* `forge ssh web uptime` runs `uptime` remotely and exits.
|
|
3708
|
+
*/
|
|
3709
|
+
function buildSshArgs(target, remoteCommand = []) {
|
|
3710
|
+
const args = [
|
|
3711
|
+
`${target.user}@${target.host}`,
|
|
3712
|
+
"-p",
|
|
3713
|
+
String(target.port)
|
|
3714
|
+
];
|
|
3715
|
+
if (remoteCommand.length > 0) args.push(...remoteCommand);
|
|
3716
|
+
return args;
|
|
3717
|
+
}
|
|
3718
|
+
//#endregion
|
|
3719
|
+
//#region src/commands/ssh/handlers.ts
|
|
3720
|
+
/**
|
|
3721
|
+
* CLI handler for `forge ssh` — open an interactive SSH session to a server.
|
|
3722
|
+
*
|
|
3723
|
+
* Resolves the server, reads its connection details from the API, then hands
|
|
3724
|
+
* off to the local `ssh` binary with an inherited stdio (interactive) session.
|
|
3725
|
+
*/
|
|
3726
|
+
/**
|
|
3727
|
+
* Connect to a server over SSH.
|
|
3728
|
+
*
|
|
3729
|
+
* @param server - Server ID or name (resolved via {@link resolveServerId}).
|
|
3730
|
+
* @param remote - Optional remote command to run instead of an interactive shell.
|
|
3731
|
+
* @param ctx - CLI command context.
|
|
3732
|
+
*/
|
|
3733
|
+
async function sshConnect(server, remote, ctx) {
|
|
3734
|
+
if (!server) exitWithValidationError("server", "forge ssh <server> [command...]", ctx.formatter);
|
|
3735
|
+
await runCommand(async () => {
|
|
3736
|
+
const token = ctx.getToken();
|
|
3737
|
+
const execCtx = ctx.createExecutorContext(token);
|
|
3738
|
+
const server_id = await resolveServerId(server, execCtx);
|
|
3739
|
+
const { data } = await getServer({ server_id }, execCtx);
|
|
3740
|
+
const target = resolveSshTarget(data, {
|
|
3741
|
+
user: typeof ctx.options.user === "string" ? ctx.options.user : void 0,
|
|
3742
|
+
private: ctx.options.private === true,
|
|
3743
|
+
port: typeof ctx.options.port === "string" ? ctx.options.port : void 0
|
|
3744
|
+
});
|
|
3745
|
+
const sshArgs = buildSshArgs(target, remote);
|
|
3746
|
+
const printable = `ssh ${sshArgs.join(" ")}`;
|
|
3747
|
+
if (ctx.formatter.isJson()) {
|
|
3748
|
+
ctx.formatter.output({
|
|
3749
|
+
command: printable,
|
|
3750
|
+
...target,
|
|
3751
|
+
args: sshArgs
|
|
3752
|
+
});
|
|
3753
|
+
return;
|
|
3754
|
+
}
|
|
3755
|
+
if (ctx.options["dry-run"] === true) {
|
|
3756
|
+
console.log(printable);
|
|
3757
|
+
return;
|
|
3758
|
+
}
|
|
3759
|
+
const auditArgs = {
|
|
3760
|
+
server: server_id,
|
|
3761
|
+
user: target.user,
|
|
3762
|
+
host: target.host,
|
|
3763
|
+
port: target.port
|
|
3764
|
+
};
|
|
3765
|
+
try {
|
|
3766
|
+
const child = spawnSync("ssh", sshArgs, { stdio: "inherit" });
|
|
3767
|
+
if (child.error) throw child.error;
|
|
3768
|
+
getCliAuditLogger().log({
|
|
3769
|
+
source: "cli",
|
|
3770
|
+
resource: "ssh",
|
|
3771
|
+
action: "connect",
|
|
3772
|
+
args: auditArgs,
|
|
3773
|
+
status: "success"
|
|
3774
|
+
});
|
|
3775
|
+
if (typeof child.status === "number" && child.status !== 0) process.exit(child.status);
|
|
3776
|
+
} catch (err) {
|
|
3777
|
+
getCliAuditLogger().log({
|
|
3778
|
+
source: "cli",
|
|
3779
|
+
resource: "ssh",
|
|
3780
|
+
action: "connect",
|
|
3781
|
+
args: auditArgs,
|
|
3782
|
+
status: "error",
|
|
3783
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3784
|
+
});
|
|
3785
|
+
throw err;
|
|
3786
|
+
}
|
|
3787
|
+
}, ctx.formatter);
|
|
3788
|
+
}
|
|
3789
|
+
//#endregion
|
|
3790
|
+
//#region src/commands/ssh/command.ts
|
|
3791
|
+
/**
|
|
3792
|
+
* Route the top-level `forge ssh` command.
|
|
3793
|
+
*
|
|
3794
|
+
* Unlike resource commands there is no sub-action: the first positional is the
|
|
3795
|
+
* server, and any remaining positionals form an optional remote command.
|
|
3796
|
+
*/
|
|
3797
|
+
async function handleSshCommand(server, remote, options) {
|
|
3798
|
+
await sshConnect(server, remote, createContext(options));
|
|
3799
|
+
}
|
|
3800
|
+
//#endregion
|
|
3801
|
+
//#region src/commands/ssh/help.ts
|
|
3802
|
+
function showSshHelp() {
|
|
3803
|
+
console.log(`
|
|
3804
|
+
${colors.bold("forge ssh")} - Open an SSH session to a server
|
|
3805
|
+
|
|
3806
|
+
${colors.bold("USAGE:")}
|
|
3807
|
+
forge ssh <server> [command...] [options]
|
|
3808
|
+
|
|
3809
|
+
${colors.bold("ARGUMENTS:")}
|
|
3810
|
+
<server> Server ID or name (required)
|
|
3811
|
+
[command...] Optional remote command to run, then exit
|
|
3812
|
+
|
|
3813
|
+
${colors.bold("OPTIONS:")}
|
|
3814
|
+
--user <name> SSH user (default: forge)
|
|
3815
|
+
--private Connect over the private IP address
|
|
3816
|
+
--port <n> Override the server's SSH port
|
|
3817
|
+
--dry-run Print the ssh command instead of connecting
|
|
3818
|
+
-f, --format json Print the resolved connection details as JSON
|
|
3819
|
+
-h, --help Show this help
|
|
3820
|
+
|
|
3821
|
+
${colors.bold("EXAMPLES:")}
|
|
3822
|
+
# Interactive session (connects as forge@<ip>)
|
|
3823
|
+
forge ssh my-server
|
|
3824
|
+
|
|
3825
|
+
# Connect as a custom user
|
|
3826
|
+
forge ssh my-server --user deploy
|
|
3827
|
+
|
|
3828
|
+
# Use the private network
|
|
3829
|
+
forge ssh my-server --private
|
|
3830
|
+
|
|
3831
|
+
# Run a one-off remote command
|
|
3832
|
+
forge ssh my-server uptime
|
|
3833
|
+
|
|
3834
|
+
# Just show the command that would run
|
|
3835
|
+
forge ssh my-server --dry-run
|
|
3836
|
+
|
|
3837
|
+
${colors.bold("NOTES:")}
|
|
3838
|
+
Requires your local SSH key to be authorized on the server; this command
|
|
3839
|
+
launches ssh, it does not upload keys.
|
|
3840
|
+
`);
|
|
3841
|
+
}
|
|
3842
|
+
//#endregion
|
|
3843
|
+
//#region src/commands/ssh-keys/handlers.ts
|
|
3338
3844
|
async function sshKeysList(ctx) {
|
|
3339
3845
|
const server = String(ctx.options.server ?? "");
|
|
3340
3846
|
if (!server) exitWithValidationError("server_id", "forge ssh-keys list --server <server_id>", ctx.formatter);
|
|
@@ -3369,7 +3875,9 @@ async function sshKeysGet(args, ctx) {
|
|
|
3369
3875
|
]);
|
|
3370
3876
|
}, ctx.formatter);
|
|
3371
3877
|
}
|
|
3372
|
-
|
|
3878
|
+
//#endregion
|
|
3879
|
+
//#region src/commands/ssh-keys/command.ts
|
|
3880
|
+
var handleSshKeysCommand = createCommandRouter({
|
|
3373
3881
|
resource: "ssh-keys",
|
|
3374
3882
|
handlers: {
|
|
3375
3883
|
list: sshKeysList,
|
|
@@ -3377,6 +3885,8 @@ const handleSshKeysCommand = createCommandRouter({
|
|
|
3377
3885
|
get: [sshKeysGet, "args"]
|
|
3378
3886
|
}
|
|
3379
3887
|
});
|
|
3888
|
+
//#endregion
|
|
3889
|
+
//#region src/commands/ssh-keys/help.ts
|
|
3380
3890
|
function showSshKeysHelp(subcommand) {
|
|
3381
3891
|
if (subcommand === "list" || subcommand === "ls") console.log(`
|
|
3382
3892
|
${colors.bold("forge ssh-keys list")} - List SSH keys on a server
|
|
@@ -3407,6 +3917,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
3407
3917
|
Run ${colors.cyan("forge ssh-keys <subcommand> --help")} for details.
|
|
3408
3918
|
`);
|
|
3409
3919
|
}
|
|
3920
|
+
//#endregion
|
|
3921
|
+
//#region src/commands/user/handlers.ts
|
|
3410
3922
|
async function userGet(ctx) {
|
|
3411
3923
|
await runCommand(async () => {
|
|
3412
3924
|
const token = ctx.getToken();
|
|
@@ -3414,10 +3926,14 @@ async function userGet(ctx) {
|
|
|
3414
3926
|
ctx.formatter.output(result.data);
|
|
3415
3927
|
}, ctx.formatter);
|
|
3416
3928
|
}
|
|
3417
|
-
|
|
3929
|
+
//#endregion
|
|
3930
|
+
//#region src/commands/user/command.ts
|
|
3931
|
+
var handleUserCommand = createCommandRouter({
|
|
3418
3932
|
resource: "user",
|
|
3419
3933
|
handlers: { get: userGet }
|
|
3420
3934
|
});
|
|
3935
|
+
//#endregion
|
|
3936
|
+
//#region src/commands/user/help.ts
|
|
3421
3937
|
function showUserHelp(subcommand) {
|
|
3422
3938
|
if (subcommand === "get") console.log(`
|
|
3423
3939
|
${colors.bold("forge user get")} - Get the authenticated user profile
|
|
@@ -3443,6 +3959,8 @@ ${colors.bold("OPTIONS:")}
|
|
|
3443
3959
|
Run ${colors.cyan("forge user <subcommand> --help")} for details.
|
|
3444
3960
|
`);
|
|
3445
3961
|
}
|
|
3962
|
+
//#endregion
|
|
3963
|
+
//#region src/utils/args.ts
|
|
3446
3964
|
function parseArgs(argv = process.argv.slice(2)) {
|
|
3447
3965
|
const options = {};
|
|
3448
3966
|
const positional = [];
|
|
@@ -3479,7 +3997,9 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
3479
3997
|
positional
|
|
3480
3998
|
};
|
|
3481
3999
|
}
|
|
3482
|
-
|
|
4000
|
+
//#endregion
|
|
4001
|
+
//#region src/cli.ts
|
|
4002
|
+
var VERSION = "0.4.6";
|
|
3483
4003
|
function showHelp() {
|
|
3484
4004
|
console.log(`
|
|
3485
4005
|
${colors.bold("forge")} v${VERSION}
|
|
@@ -3538,6 +4058,9 @@ ${colors.bold("COMMANDS:")}
|
|
|
3538
4058
|
list, ls List firewall rules (requires --server)
|
|
3539
4059
|
get <id> Get firewall rule details (requires --server)
|
|
3540
4060
|
|
|
4061
|
+
ssh <server> Open an SSH session to a server
|
|
4062
|
+
--user <name> (default: forge), --private, --port <n>
|
|
4063
|
+
|
|
3541
4064
|
ssh-keys Manage SSH keys
|
|
3542
4065
|
list, ls List SSH keys (requires --server)
|
|
3543
4066
|
get <id> Get SSH key details (requires --server)
|
|
@@ -3559,6 +4082,10 @@ ${colors.bold("COMMANDS:")}
|
|
|
3559
4082
|
create Create a scheduled job (requires --server --command)
|
|
3560
4083
|
delete <id> Delete a scheduled job (requires --server)
|
|
3561
4084
|
|
|
4085
|
+
services List and restart server services
|
|
4086
|
+
list, ls List services on a server (forge services list <server>)
|
|
4087
|
+
restart <service> Restart a service (forge services restart <server> <service>)
|
|
4088
|
+
|
|
3562
4089
|
user Display authenticated user profile
|
|
3563
4090
|
get Get the authenticated user profile
|
|
3564
4091
|
|
|
@@ -3647,7 +4174,7 @@ async function main() {
|
|
|
3647
4174
|
showHelp();
|
|
3648
4175
|
process.exit(0);
|
|
3649
4176
|
}
|
|
3650
|
-
if (options.version || options.v) {
|
|
4177
|
+
if (options.version === true || options.v === true) {
|
|
3651
4178
|
console.log(VERSION);
|
|
3652
4179
|
process.exit(0);
|
|
3653
4180
|
}
|
|
@@ -3740,6 +4267,13 @@ async function main() {
|
|
|
3740
4267
|
}
|
|
3741
4268
|
await handleFirewallRulesCommand(subcommand ?? "list", positional, options);
|
|
3742
4269
|
break;
|
|
4270
|
+
case "ssh":
|
|
4271
|
+
if (wantsHelp) {
|
|
4272
|
+
showSshHelp();
|
|
4273
|
+
process.exit(0);
|
|
4274
|
+
}
|
|
4275
|
+
await handleSshCommand(subcommand, positional, options);
|
|
4276
|
+
break;
|
|
3743
4277
|
case "ssh-keys":
|
|
3744
4278
|
if (wantsHelp) {
|
|
3745
4279
|
showSshKeysHelp(subcommand);
|
|
@@ -3768,6 +4302,13 @@ async function main() {
|
|
|
3768
4302
|
}
|
|
3769
4303
|
await handleScheduledJobsCommand(subcommand ?? "list", positional, options);
|
|
3770
4304
|
break;
|
|
4305
|
+
case "services":
|
|
4306
|
+
if (wantsHelp) {
|
|
4307
|
+
showServicesHelp(subcommand);
|
|
4308
|
+
process.exit(0);
|
|
4309
|
+
}
|
|
4310
|
+
await handleServicesCommand(subcommand ?? "list", positional, options);
|
|
4311
|
+
break;
|
|
3771
4312
|
case "user":
|
|
3772
4313
|
if (wantsHelp) {
|
|
3773
4314
|
showUserHelp(subcommand);
|
|
@@ -3831,5 +4372,6 @@ main().catch((error) => {
|
|
|
3831
4372
|
console.error(colors.red("Unhandled error:"), error);
|
|
3832
4373
|
process.exit(1);
|
|
3833
4374
|
});
|
|
4375
|
+
//#endregion
|
|
3834
4376
|
|
|
3835
4377
|
//# sourceMappingURL=cli.js.map
|