Skip to content

Commit e5ed9f4

Browse files
authored
VSCODE-115: Launch mongoshell cross platform (#130)
1 parent 863c747 commit e5ed9f4

File tree

11 files changed

+439
-218
lines changed

11 files changed

+439
-218
lines changed

package.json

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@
160160
"command": "mdb.openMongoDBShell",
161161
"title": "MongoDB: Launch MongoDB Shell"
162162
},
163+
{
164+
"command": "mdb.treeViewOpenMongoDBShell",
165+
"title": "Launch MongoDB Shell"
166+
},
163167
{
164168
"command": "mdb.createPlayground",
165169
"title": "MongoDB: Create MongoDB Playground"
@@ -318,24 +322,29 @@
318322
"group": "1@2"
319323
},
320324
{
321-
"command": "mdb.renameConnection",
325+
"command": "mdb.treeViewOpenMongoDBShell",
322326
"when": "view == mongoDB && viewItem == connectedConnectionTreeItem",
323327
"group": "2@1"
324328
},
325329
{
326-
"command": "mdb.copyConnectionString",
330+
"command": "mdb.renameConnection",
327331
"when": "view == mongoDB && viewItem == connectedConnectionTreeItem",
328332
"group": "3@1"
329333
},
330334
{
331-
"command": "mdb.disconnectFromConnectionTreeItem",
335+
"command": "mdb.copyConnectionString",
332336
"when": "view == mongoDB && viewItem == connectedConnectionTreeItem",
333337
"group": "4@1"
334338
},
339+
{
340+
"command": "mdb.disconnectFromConnectionTreeItem",
341+
"when": "view == mongoDB && viewItem == connectedConnectionTreeItem",
342+
"group": "5@1"
343+
},
335344
{
336345
"command": "mdb.treeItemRemoveConnection",
337346
"when": "view == mongoDB && viewItem == connectedConnectionTreeItem",
338-
"group": "4@2"
347+
"group": "5@2"
339348
},
340349
{
341350
"command": "mdb.connectToConnectionTreeItem",
@@ -455,6 +464,10 @@
455464
"command": "mdb.connectToConnectionTreeItem",
456465
"when": "false"
457466
},
467+
{
468+
"command": "mdb.treeViewOpenMongoDBShell",
469+
"when": "false"
470+
},
458471
{
459472
"command": "mdb.disconnectFromConnectionTreeItem",
460473
"when": "false"

src/commands/launchMongoShell.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import * as vscode from 'vscode';
2+
3+
import ConnectionController from '../connectionController';
4+
5+
function isSslConnection(activeConnectionModel: any): boolean {
6+
return !!(
7+
activeConnectionModel &&
8+
activeConnectionModel.driverOptions &&
9+
(activeConnectionModel.driverOptions.sslCA ||
10+
activeConnectionModel.driverOptions.sslCert ||
11+
activeConnectionModel.driverOptions.sslPass)
12+
);
13+
}
14+
15+
function getSslOptions(driverOptions: any): string[] {
16+
const mdbSslOptions = [ '--ssl' ];
17+
18+
if (!driverOptions.checkServerIdentity) {
19+
mdbSslOptions.push('--sslAllowInvalidHostnames');
20+
}
21+
22+
if (!driverOptions.sslValidate) {
23+
mdbSslOptions.push('--sslAllowInvalidCertificates');
24+
}
25+
26+
if (driverOptions.sslCA) {
27+
mdbSslOptions.push(`--sslCAFile=${driverOptions.sslCA}`);
28+
}
29+
30+
if (driverOptions.sslCert) {
31+
mdbSslOptions.push(`--sslPEMKeyFile=${driverOptions.sslCert}`);
32+
}
33+
34+
if (driverOptions.sslPass) {
35+
mdbSslOptions.push(`--sslPEMKeyPassword=${driverOptions.sslPass}`);
36+
}
37+
38+
return mdbSslOptions;
39+
}
40+
41+
export default function openMongoDBShell(connectionController: ConnectionController): Promise<boolean> {
42+
let mdbSslOptions: string[] = [];
43+
44+
if (
45+
!connectionController.isCurrentlyConnected()
46+
) {
47+
vscode.window.showErrorMessage(
48+
'You need to be connected before launching the MongoDB Shell.'
49+
);
50+
51+
return Promise.resolve(false);
52+
}
53+
54+
const userShell = vscode.env.shell;
55+
const shellCommand: string | undefined = vscode.workspace.getConfiguration('mdb').get('shell');
56+
57+
if (!userShell) {
58+
vscode.window.showErrorMessage(
59+
'Error: No shell found, please set your default shell environment in vscode.'
60+
);
61+
62+
return Promise.resolve(false);
63+
}
64+
65+
if (!shellCommand) {
66+
vscode.window.showErrorMessage(
67+
'No MongoDB shell command found. Please set the shell command in the MongoDB extension settings.'
68+
);
69+
return Promise.resolve(false);
70+
}
71+
72+
const activeConnectionModel = connectionController
73+
.getActiveConnectionModel()
74+
?.getAttributes({ derived: true });
75+
76+
const mdbConnectionString = activeConnectionModel
77+
? activeConnectionModel.driverUrlWithSsh
78+
: '';
79+
80+
if (activeConnectionModel && isSslConnection(activeConnectionModel)) {
81+
mdbSslOptions = getSslOptions(activeConnectionModel.driverOptions);
82+
}
83+
84+
const isWindowsBasedShell = userShell.includes('cmd.exe') || userShell.includes('powershell.exe');
85+
if (isWindowsBasedShell) {
86+
const mongoDBShell = vscode.window.createTerminal({
87+
name: 'MongoDB Shell',
88+
env: {
89+
MDB_CONNECTION_STRING: mdbConnectionString
90+
}
91+
});
92+
93+
const mdbSslOptionsString = mdbSslOptions.length > 0
94+
? `${mdbSslOptions.join(' ')} `
95+
: '';
96+
97+
mongoDBShell.sendText(
98+
`${shellCommand} ${mdbSslOptionsString}%MDB_CONNECTION_STRING%;`
99+
);
100+
mongoDBShell.show();
101+
} else {
102+
// Assume it's a bash environment. This may fail on certain
103+
// shells but should cover most cases.
104+
const mongoDBShell = vscode.window.createTerminal({
105+
name: 'MongoDB Shell',
106+
shellPath: shellCommand,
107+
shellArgs: [
108+
mdbConnectionString,
109+
...mdbSslOptions
110+
]
111+
});
112+
113+
mongoDBShell.show();
114+
}
115+
116+
return Promise.resolve(true);
117+
}

src/mdbExtensionController.ts

Lines changed: 7 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import * as vscode from 'vscode';
77

88
import ConnectionController from './connectionController';
9+
import launchMongoShell from './commands/launchMongoShell';
910
import { EditorsController, PlaygroundController } from './editors';
1011
import { ExplorerController, CollectionTreeItem } from './explorer';
1112
import { LanguageServerController } from './language';
@@ -101,7 +102,12 @@ export default class MDBExtensionController implements vscode.Disposable {
101102
this._connectionController.onRemoveMongoDBConnection()
102103
);
103104

104-
this.registerCommand('mdb.openMongoDBShell', () => this.openMongoDBShell());
105+
this.registerCommand('mdb.openMongoDBShell', () =>
106+
launchMongoShell(this._connectionController)
107+
);
108+
this.registerCommand('mdb.treeViewOpenMongoDBShell', () =>
109+
launchMongoShell(this._connectionController)
110+
);
105111

106112
this.registerCommand('mdb.createPlayground', () =>
107113
this._playgroundController.createPlayground()
@@ -397,90 +403,6 @@ export default class MDBExtensionController implements vscode.Disposable {
397403
);
398404
}
399405

400-
private isSslConnection(activeConnectionModel: any): boolean {
401-
return !!(
402-
activeConnectionModel &&
403-
activeConnectionModel.driverOptions &&
404-
(activeConnectionModel.driverOptions.sslCA ||
405-
activeConnectionModel.driverOptions.sslCert ||
406-
activeConnectionModel.driverOptions.sslPass)
407-
);
408-
}
409-
410-
private getSslOptionsString(driverOptions: any): string {
411-
let mdbSslOptionsString = '--ssl';
412-
413-
if (!driverOptions.checkServerIdentity) {
414-
mdbSslOptionsString = `${mdbSslOptionsString} --sslAllowInvalidHostnames`;
415-
}
416-
417-
if (!driverOptions.sslValidate) {
418-
mdbSslOptionsString = `${mdbSslOptionsString} --sslAllowInvalidCertificates`;
419-
}
420-
421-
if (driverOptions.sslCA) {
422-
mdbSslOptionsString = `${mdbSslOptionsString} --sslCAFile ${driverOptions.sslCA}`;
423-
}
424-
425-
if (driverOptions.sslCert) {
426-
mdbSslOptionsString = `${mdbSslOptionsString} --sslPEMKeyFile ${driverOptions.sslCert}`;
427-
}
428-
429-
if (driverOptions.sslPass) {
430-
mdbSslOptionsString = `${mdbSslOptionsString} --sslPEMKeyPassword $MDB_SSL_CERTIFICATE_KEY_FILE_PASSWORD`;
431-
}
432-
433-
return mdbSslOptionsString;
434-
}
435-
436-
public openMongoDBShell(): Promise<boolean> {
437-
const mongoDBShellEnv: any = {};
438-
let mdbSslOptionsString = '';
439-
440-
if (
441-
!this._connectionController ||
442-
!this._connectionController.isCurrentlyConnected()
443-
) {
444-
vscode.window.showErrorMessage(
445-
'You need to be connected before launching the MongoDB Shell.'
446-
);
447-
448-
return Promise.resolve(false);
449-
}
450-
451-
const activeConnectionModel = this._connectionController
452-
.getActiveConnectionModel()
453-
?.getAttributes({ derived: true });
454-
455-
mongoDBShellEnv['MDB_CONNECTION_STRING'] = activeConnectionModel
456-
? activeConnectionModel.driverUrlWithSsh
457-
: '';
458-
459-
if (activeConnectionModel && this.isSslConnection(activeConnectionModel)) {
460-
mdbSslOptionsString = this.getSslOptionsString(
461-
activeConnectionModel.driverOptions
462-
);
463-
464-
if (activeConnectionModel.driverOptions.sslPass) {
465-
mongoDBShellEnv['MDB_SSL_CERTIFICATE_KEY_FILE_PASSWORD'] =
466-
activeConnectionModel.driverOptions.sslPass;
467-
}
468-
}
469-
470-
const shellCommand = vscode.workspace.getConfiguration('mdb').get('shell');
471-
const mongoDBShell = vscode.window.createTerminal({
472-
name: 'MongoDB Shell',
473-
env: mongoDBShellEnv
474-
});
475-
476-
mongoDBShell.sendText(
477-
`${shellCommand} ${mdbSslOptionsString} $MDB_CONNECTION_STRING; unset MDB_CONNECTION_STRING; unset MDB_SSL_CERTIFICATE_KEY_FILE_PASSWORD`
478-
);
479-
mongoDBShell.show();
480-
481-
return Promise.resolve(true);
482-
}
483-
484406
dispose(): void {
485407
this.deactivate();
486408
}

0 commit comments

Comments
 (0)