bdy 1.22.94-master → 1.22.94
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/distTs/package.json
CHANGED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("../../utils");
|
|
7
|
+
const texts_1 = require("../../texts");
|
|
8
|
+
const output_1 = __importDefault(require("../../output"));
|
|
9
|
+
const input_1 = __importDefault(require("../../input"));
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const commandSandboxSsh = (0, utils_1.newCommand)('ssh', texts_1.DESC_COMMAND_SANDBOX_SSH);
|
|
12
|
+
commandSandboxSsh.alias('connect');
|
|
13
|
+
commandSandboxSsh.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
|
|
14
|
+
commandSandboxSsh.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
|
|
15
|
+
commandSandboxSsh.option('-i, --identity <path>', texts_1.OPTION_SANDBOX_SSH_IDENTITY);
|
|
16
|
+
commandSandboxSsh.option('--print', texts_1.OPTION_SANDBOX_SSH_PRINT);
|
|
17
|
+
commandSandboxSsh.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
|
|
18
|
+
commandSandboxSsh.argument('[args...]', texts_1.OPTION_SANDBOX_SSH_ARGS);
|
|
19
|
+
commandSandboxSsh.addHelpText('after', `\nEXAMPLES:${texts_1.EXAMPLE_SANDBOX_SSH}`);
|
|
20
|
+
// ssh keeps the FIRST value it is given for a keyword, so every default below would silently beat
|
|
21
|
+
// the same -o coming from the user. Only add ours when they did not set that keyword themselves.
|
|
22
|
+
const hasSshOption = (args, keyword) => {
|
|
23
|
+
const prefix = `${keyword.toLowerCase()}=`;
|
|
24
|
+
return args.some((arg, i) => {
|
|
25
|
+
let value = '';
|
|
26
|
+
if (args[i - 1] === '-o')
|
|
27
|
+
value = arg;
|
|
28
|
+
else if (arg.startsWith('-o'))
|
|
29
|
+
value = arg.slice(2);
|
|
30
|
+
return value.toLowerCase().startsWith(prefix);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
const buildSshArgs = (host, port, identity, extra) => {
|
|
34
|
+
const args = ['-p', String(port)];
|
|
35
|
+
if (identity)
|
|
36
|
+
args.push('-i', identity);
|
|
37
|
+
// The host key belongs to the agent inside the sandbox and is regenerated for every new sandbox,
|
|
38
|
+
// while the edge host is shared and only the forward port varies - a recycled port would trip a
|
|
39
|
+
// host key mismatch in the user's own known_hosts. Keep those keys in ~/.bdy instead.
|
|
40
|
+
if (!hasSshOption(extra, 'UserKnownHostsFile')) {
|
|
41
|
+
args.push('-o', `UserKnownHostsFile=${(0, path_1.join)((0, utils_1.getHomeDirectory)(), 'known_hosts')}`);
|
|
42
|
+
}
|
|
43
|
+
if (!hasSshOption(extra, 'StrictHostKeyChecking')) {
|
|
44
|
+
args.push('-o', 'StrictHostKeyChecking=accept-new');
|
|
45
|
+
}
|
|
46
|
+
// Only publickey reaches a shell: on the password path the agent accepts without opening the
|
|
47
|
+
// proxy connection to the sandbox sshd, so pty and shell requests are rejected afterwards.
|
|
48
|
+
if (!hasSshOption(extra, 'PreferredAuthentications')) {
|
|
49
|
+
args.push('-o', 'PreferredAuthentications=publickey');
|
|
50
|
+
}
|
|
51
|
+
args.push(host, ...extra);
|
|
52
|
+
return args;
|
|
53
|
+
};
|
|
54
|
+
const quoteArg = (arg) => /[\s'"\\$`*?[\]{}();&|<>#~]/.test(arg) ? `'${arg.replace(/'/g, "'\\''")}'` : arg;
|
|
55
|
+
commandSandboxSsh.action(async (identifier, args, options) => {
|
|
56
|
+
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
57
|
+
const project = input_1.default.restApiProject(options.project);
|
|
58
|
+
const client = input_1.default.restApiTokenClient();
|
|
59
|
+
const { sandbox_id } = await client.getSandboxByIdentifier(workspace, project, identifier);
|
|
60
|
+
if (!sandbox_id) {
|
|
61
|
+
output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
|
|
62
|
+
}
|
|
63
|
+
let sandbox = await client.getSandbox(workspace, sandbox_id);
|
|
64
|
+
if (sandbox.status !== utils_1.SANDBOX_STATUS.RUNNING) {
|
|
65
|
+
output_1.default.exitError((0, texts_1.ERR_SANDBOX_NOT_RUNNING)(identifier, sandbox.status || 'UNKNOWN'));
|
|
66
|
+
}
|
|
67
|
+
if (!sandbox.ssh_host || !sandbox.ssh_port) {
|
|
68
|
+
// A sandbox that just became RUNNING may not have its forward port registered yet
|
|
69
|
+
try {
|
|
70
|
+
sandbox = await client.sandboxWaitForPorts(workspace, sandbox_id, 30);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
output_1.default.exitError((0, texts_1.ERR_SANDBOX_SSH_NO_ACCESS)(identifier));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const sshArgs = buildSshArgs(sandbox.ssh_host, sandbox.ssh_port, options.identity, args || []);
|
|
77
|
+
if (options.print) {
|
|
78
|
+
output_1.default.normal(['ssh', ...sshArgs].map(quoteArg).join(' '));
|
|
79
|
+
output_1.default.exitNormal();
|
|
80
|
+
}
|
|
81
|
+
const which = require('which');
|
|
82
|
+
const resolved = await which('ssh', { nothrow: true });
|
|
83
|
+
if (!resolved) {
|
|
84
|
+
output_1.default.exitError(texts_1.ERR_SANDBOX_SSH_MISSING);
|
|
85
|
+
}
|
|
86
|
+
const { spawn } = require('cross-spawn');
|
|
87
|
+
const child = spawn(resolved, sshArgs, { stdio: 'inherit' });
|
|
88
|
+
// The terminal sends Ctrl+C to the whole foreground group: exiting here would detach a live ssh
|
|
89
|
+
// and hand the prompt back while it still owns the tty. Let ssh be the one that handles it.
|
|
90
|
+
const ignoreSignals = ['SIGINT', 'SIGQUIT', 'SIGTSTP'];
|
|
91
|
+
ignoreSignals.forEach((signal) => process.on(signal, () => { }));
|
|
92
|
+
child.on('error', () => {
|
|
93
|
+
output_1.default.exitError(texts_1.ERR_SANDBOX_SSH_MISSING);
|
|
94
|
+
});
|
|
95
|
+
child.on('close', (code, signal) => {
|
|
96
|
+
output_1.default.exitCode(signal ? 1 : code || 0);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
exports.default = commandSandboxSsh;
|