-
Notifications
You must be signed in to change notification settings - Fork 8
/
index.js
113 lines (96 loc) · 3.22 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
'use strict';
const RSVP = require('rsvp');
const fs = require('fs');
const { createTunnel } = require('tunnel-ssh');
const untildify = require('untildify');
const DeployPluginBase = require('ember-cli-deploy-plugin');
const MAX_PORT_NUMBER = 65535;
const MIN_PORT_NUMBER = 49151;
module.exports = {
name: 'ember-cli-deploy-ssh-tunnel',
createDeployPlugin: function (options) {
const DeployPlugin = DeployPluginBase.extend({
name: options.name,
defaultConfig: {
dstPort: 6379,
port: 22,
dstHost: 'localhost',
srcPort: function () {
var range = MAX_PORT_NUMBER - MIN_PORT_NUMBER + 1;
return Math.floor(Math.random() * range) + MIN_PORT_NUMBER;
},
tunnelClient: function (context) {
// if you want to provide your own ssh client to be used instead of one from this plugin,
// must follow this signature
// createTunnel(
// tunnelOptions: TunnelOptions,
// serverOptions: ServerOptions,
// sshOptions: SshOptions,
// forwardOptions: ForwardOptions
// ): Promise<[Server, Client]>;
// https://github.com/agebrock/tunnel-ssh/blob/master/types/index.d.ts
return context.tunnelClient || createTunnel;
}
},
requiredConfig: ['host', 'username'],
setup: function (/* context */) {
const srcPort = this.readConfig('srcPort');
if (srcPort > MAX_PORT_NUMBER || srcPort < MIN_PORT_NUMBER) {
throw (
'Port ' +
srcPort +
' is not available to open a SSH connection on.\n' +
'Please choose a port between ' +
MIN_PORT_NUMBER +
' and ' +
MAX_PORT_NUMBER +
'.'
);
}
const tunnel = this.readConfig('tunnelClient');
let privateKey = this.readConfig('privateKey');
if (this.readConfig('privateKeyPath')) {
privateKey = fs.readFileSync(untildify(this.readConfig('privateKeyPath')));
}
const tunnelOptions = {
autoClose: true
};
const serverOptions = {
port: srcPort
};
const sshOptions = {
host: this.readConfig('host'),
port: this.readConfig('port'),
username: this.readConfig('username'),
password: this.readConfig('password'),
privateKey,
passphrase: this.readConfig('passphrase')
};
const forwardOptions = {
srcAddr: 'localhost',
srcPort: this.readConfig('srcPort'),
dstAddr: this.readConfig('dstHost'),
dstPort: this.readConfig('dstPort')
};
return new RSVP.Promise(function (resolve, reject) {
tunnel(tunnelOptions, serverOptions, sshOptions, forwardOptions)
.then(([server]) => {
resolve({
tunnel: {
handler: server,
srcPort: srcPort
}
});
})
.catch((error) => {
reject(error);
});
});
},
teardown: function (context) {
context.tunnel.handler.close();
}
});
return new DeployPlugin();
}
};