Skip to content

Commit ec0c498

Browse files
authored
Support connections over SSH (#1447)
* Add SSH connection settings and options to IConnection interface * Add SSH tunneling support to AbstractDriver class * Bump base-driver version to 0.2.0 * Update README.md to include changelog for SSH tunneling support
1 parent b904f19 commit ec0c498

File tree

5 files changed

+141
-4
lines changed

5 files changed

+141
-4
lines changed

packages/base-driver/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ Inactive icon: Opacity 50%, no margins and paddings
1212

1313
## Changelog
1414

15+
### v0.2.0
16+
17+
- Added SSH tunneling support.
18+
1519
### v0.1.11
1620

1721
- Fix `toAbsolutePath` for Windows by using `vscode-uri`.

packages/base-driver/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sqltools/base-driver",
3-
"version": "0.1.11",
3+
"version": "0.2.0",
44
"description": "SQLTools Base Driver",
55
"publishConfig": {
66
"access": "public",
@@ -45,6 +45,7 @@
4545
"env-paths": "^2.2.0",
4646
"make-dir": "^3.1.0",
4747
"resolve": "^1.17.0",
48+
"tunnel-ssh": "^5.2.0",
4849
"vscode-languageserver": "6.1.1"
4950
}
5051
}

packages/base-driver/src/index.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import sqltoolsRequire, { sqltoolsResolve } from './lib/require';
1616
import { createLogger } from '@sqltools/log';
1717
import path from 'path';
1818
import fs from 'fs';
19-
import {URI} from 'vscode-uri';
19+
import { URI } from 'vscode-uri';
20+
import { createTunnel } from 'tunnel-ssh';
21+
import { AddressInfo } from 'net';
2022

2123
export default abstract class AbstractDriver<ConnectionType extends any, DriverOptions extends any> implements IConnectionDriver {
2224
public log: ReturnType<typeof createLogger>;
@@ -129,6 +131,41 @@ export default abstract class AbstractDriver<ConnectionType extends any, DriverO
129131
return { message: message.toString(), date: new Date() };
130132
}
131133

134+
protected async createSshTunnel(
135+
ssh: {
136+
host: string;
137+
port: number;
138+
username: string;
139+
password?: string;
140+
privateKeyPath?: string;
141+
},
142+
db: {
143+
host: string;
144+
port: number;
145+
}
146+
) {
147+
const [sshTunnel] = await createTunnel(
148+
{
149+
autoClose: true,
150+
reconnectOnError: false,
151+
},
152+
null,
153+
{
154+
host: ssh.host,
155+
port: ssh.port,
156+
username: ssh.username,
157+
privateKey: fs.readFileSync(ssh.privateKeyPath),
158+
},
159+
{
160+
dstAddr: db.host,
161+
dstPort: db.port,
162+
}
163+
);
164+
return {
165+
port: (sshTunnel.address() as AddressInfo).port,
166+
};
167+
}
168+
132169
static readonly CONSTANTS = {
133170
DEPENDENCY_PACKAGE: 'package' as NodeDependency['type'],
134171
DEPENDENCY_NPM_SCRIPT: 'npmscript' as NodeDependency['type'],

packages/types/index.d.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,58 @@ export interface IConnection<DriverOptions = any> {
200200
[key: string]: string
201201
}
202202

203+
/**
204+
* SSH connection setting, 'Enabled' or 'Disabled'
205+
* @type {string}
206+
* @default "Disabled"
207+
* @memberof IConnection
208+
*/
209+
ssh?: 'Enabled' | 'Disabled';
210+
211+
/**
212+
* SSH connection options. Required when ssh is 'Enabled'
213+
* @type {object}
214+
* @memberof IConnection
215+
*/
216+
sshOptions?: {
217+
/**
218+
* SSH server address
219+
* @type {string}
220+
* @memberof IConnection.sshOptions
221+
*/
222+
host: string;
223+
224+
/**
225+
* SSH port
226+
* @type {number}
227+
* @default 22
228+
* @memberof IConnection.sshOptions
229+
*/
230+
port: number;
231+
232+
/**
233+
* SSH username
234+
* @type {string}
235+
* @memberof IConnection.sshOptions
236+
*/
237+
username: string;
238+
239+
/**
240+
* SSH password. You can use option askForPassword to prompt password before connect
241+
* @type {string}
242+
* @default null
243+
* @memberof IConnection.sshOptions
244+
*/
245+
password?: string;
246+
247+
/**
248+
* Path to private key file
249+
* @type {string}
250+
* @memberof IConnection.sshOptions
251+
*/
252+
privateKeyPath?: string;
253+
};
254+
203255
// WONT BE INCLUDED IN SETTINGS
204256
/**
205257
* Connection flag. This is not a setting. It is determined at runtime

yarn.lock

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,7 +1844,7 @@
18441844
dependencies:
18451845
"@sinonjs/commons" "^1.7.0"
18461846

1847-
"@sqltools/base-driver@latest":
1847+
"@sqltools/base-driver@^0.1.11", "@sqltools/base-driver@latest":
18481848
version "0.1.11"
18491849
resolved "https://registry.npmjs.org/@sqltools/base-driver/-/base-driver-0.1.11.tgz"
18501850
integrity sha512-HvmblI2MbdZUkDGIjU87FTiE/Q1NfIM6SFQJGbg5Y2vCHQ8mkUnU8QS+ANbeq3YChDpjLH+b3EHq4zdavIGk5Q==
@@ -2411,6 +2411,13 @@ asap@~2.0.6:
24112411
resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz"
24122412
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
24132413

2414+
asn1@^0.2.6:
2415+
version "0.2.6"
2416+
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
2417+
integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
2418+
dependencies:
2419+
safer-buffer "~2.1.0"
2420+
24142421
asn1@~0.2.3:
24152422
version "0.2.4"
24162423
resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz"
@@ -2591,7 +2598,7 @@ base@^0.11.1:
25912598
mixin-deep "^1.2.0"
25922599
pascalcase "^0.1.1"
25932600

2594-
bcrypt-pbkdf@^1.0.0:
2601+
bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
25952602
version "1.0.2"
25962603
resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz"
25972604
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
@@ -2753,6 +2760,11 @@ buffers@~0.1.1:
27532760
resolved "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz"
27542761
integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s=
27552762

2763+
buildcheck@~0.0.6:
2764+
version "0.0.6"
2765+
resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238"
2766+
integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==
2767+
27562768
cacache@^15.2.0:
27572769
version "15.3.0"
27582770
resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb"
@@ -3170,6 +3182,14 @@ [email protected], core-util-is@~1.0.0:
31703182
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
31713183
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
31723184

3185+
cpu-features@~0.0.10:
3186+
version "0.0.10"
3187+
resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.10.tgz#9aae536db2710c7254d7ed67cb3cbc7d29ad79c5"
3188+
integrity sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==
3189+
dependencies:
3190+
buildcheck "~0.0.6"
3191+
nan "^2.19.0"
3192+
31733193
create-require@^1.1.0:
31743194
version "1.1.1"
31753195
resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz"
@@ -6311,6 +6331,11 @@ nan@^2.12.1:
63116331
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
63126332
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
63136333

6334+
nan@^2.19.0, nan@^2.20.0:
6335+
version "2.22.2"
6336+
resolved "https://registry.yarnpkg.com/nan/-/nan-2.22.2.tgz#6b504fd029fb8f38c0990e52ad5c26772fdacfbb"
6337+
integrity sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==
6338+
63146339
nanoid@^2.1.0:
63156340
version "2.1.11"
63166341
resolved "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz"
@@ -7907,6 +7932,17 @@ sqlstring@^2.3.2:
79077932
resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c"
79087933
integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==
79097934

7935+
ssh2@^1.15.0:
7936+
version "1.16.0"
7937+
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.16.0.tgz#79221d40cbf4d03d07fe881149de0a9de928c9f0"
7938+
integrity sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==
7939+
dependencies:
7940+
asn1 "^0.2.6"
7941+
bcrypt-pbkdf "^1.0.2"
7942+
optionalDependencies:
7943+
cpu-features "~0.0.10"
7944+
nan "^2.20.0"
7945+
79107946
sshpk@^1.7.0:
79117947
version "1.16.1"
79127948
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz"
@@ -8349,6 +8385,13 @@ tunnel-agent@^0.6.0:
83498385
dependencies:
83508386
safe-buffer "^5.0.1"
83518387

8388+
tunnel-ssh@^5.2.0:
8389+
version "5.2.0"
8390+
resolved "https://registry.yarnpkg.com/tunnel-ssh/-/tunnel-ssh-5.2.0.tgz#199df96b07f1fa833d578e47a5801da4af065b2a"
8391+
integrity sha512-IGiyhE2RSt3NVvZ7aKH3ykziAxKNPe/z97Rab/lrIXslif/cq7J/m6EXfERlDITiFyGGYMqqi5SSrt/mk1VbEg==
8392+
dependencies:
8393+
ssh2 "^1.15.0"
8394+
83528395
83538396
version "0.0.6"
83548397
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"

0 commit comments

Comments
 (0)