Skip to content

Commit 88c63fc

Browse files
committed
Merge pull request #4 from typeoneerror/ssh-agent
Defaults to ssh-agent instead of privateKeyPath
2 parents 66d9453 + 961e49a commit 88c63fc

File tree

6 files changed

+149
-43
lines changed

6 files changed

+149
-43
lines changed

.travis.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
language: node_js
3+
node_js:
4+
- "0.12"
5+
6+
sudo: false
7+
8+
cache:
9+
directories:
10+
- node_modules
11+
12+
before_install:
13+
- "npm config set spin false"
14+
- "npm install -g npm@^2"
15+
16+
install:
17+
- npm install -g bower
18+
- npm install
19+
- bower install
20+
21+
script:
22+
- npm test

README.md

+41-9
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,19 @@ For detailed information on how configuration of plugins works, please refer to
6262

6363
### username (`required`)
6464

65-
The user for the ssh connection
65+
The user for the ssh connection.
6666

6767
*Default:* `undefined`
6868

6969
### host (`required`)
7070

71-
The server to connect to
71+
The server to connect to.
7272

7373
*Default:* `undefined`
7474

7575
### dstPort
7676

77-
The port to forward from the server
77+
The port to forward from the server.
7878

7979
*Default:* `6379`
8080

@@ -86,31 +86,63 @@ The host to forward to on the destination server.
8686

8787
### srcPort
8888

89-
The local port for the forwarding
89+
The local port for the forwarding.
9090

9191
*Default:* a random port between `49151` and `65535`
9292

9393
### privateKeyPath
9494

95-
The local path to your ssh private key
95+
The local path to your ssh private key.
9696

97-
*Default:* `~/.ssh/id_rsa`
97+
*Default:* null
98+
99+
### password
100+
101+
Authorization string for the ssh connection.
102+
103+
*Default:* null
98104

99105
### tunnelClient
100106

101107
The client used to create the ssh tunnel. This allows the user the ability to use their own client for uploading instead of the one provided by this plugin.
102108

103109
*Default:* the tunnel provided by `tunnel-ssh`
104110

105-
## Running Tests
111+
## Authorization
106112

107-
- `npm test`
113+
ember-cli-deploy-ssh-tunnel uses the [tunnel-ssh](https://github.com/Finanzchef24-GmbH/tunnel-ssh) module to provide the SSH tunnel. Two options exist to configure tunnel-ssh from ember-cli-deploy-ssh-tunnel: `privateKeyPath` and `password`. By default, we assume you have created a public and private key and added it to ssh-agent as described in the [default GitHub setup](https://help.github.com/articles/generating-ssh-keys/).
108114

109-
[1]: http://ember-cli.github.io/ember-cli-deploy/plugins "Plugin Documentation"
115+
If no authentication information is delivered to tunnel-ssh, it will [default to using ssh-agent](https://github.com/Finanzchef24-GmbH/tunnel-ssh), so it will default to using the default id_rsa keys generated as described in the GitHub article. This includes password-protected SSH keys. If you would like to use a different SSH key, set the `privateKeyPath` option:
116+
117+
```js
118+
ENV['ssh-tunnel'] = {
119+
username: 'yourname',
120+
host: 'yourserver',
121+
privateKeyPath: '~/.ssh/another_key_rsa'
122+
};
123+
```
110124

125+
If you just want to use a password to tunnel, you can specify that as an option (we recommend using environmental variables in an .env file):
126+
127+
```js
128+
ENV['ssh-tunnel'] = {
129+
username: 'yourname',
130+
host: 'yourserver',
131+
password: process.env.SSH_PASSWORD
132+
};
133+
```
134+
135+
NOTE: at this time, this plugin does not support setting a path to `privateKeyPath` to a key that has been encrypted with a password.
136+
137+
## Running Tests
138+
139+
1. `npm install`
140+
2. `npm test`
111141

112142
## Thanks to:
113143

114144
@lukemelia and @achambers and the other folks from the ember-cli-deploy project.
115145

116146
@tim-evans for the original implementation in [ember-deploy-redis](https://github.com/LevelbossMike/ember-deploy-redis)
147+
148+
[1]: http://ember-cli.github.io/ember-cli-deploy/plugins "Plugin Documentation"

index.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/* jshint node: true */
22
'use strict';
33

4-
var Promise = require('ember-cli/lib/ext/promise');
5-
var fs = require('fs');
4+
var Promise = require('ember-cli/lib/ext/promise');
5+
var fs = require('fs');
66
var tunnelSsh = require('tunnel-ssh');
7-
var untildify = require('untildify');
7+
var untildify = require('untildify');
88

99
var DeployPluginBase = require('ember-cli-deploy-plugin');
1010

@@ -24,7 +24,6 @@ module.exports = {
2424
var range = MAX_PORT_NUMBER - MIN_PORT_NUMBER + 1;
2525
return Math.floor(Math.random() * range) + MIN_PORT_NUMBER;
2626
},
27-
privateKeyPath: '~/.ssh/id_rsa',
2827
tunnelClient: function(context) {
2928
// if you want to provide your own ssh client to be used instead of one from this plugin
3029
return context.tunnelClient || tunnelSsh;
@@ -45,18 +44,21 @@ module.exports = {
4544
dstPort: this.readConfig('dstPort'),
4645
dstHost: this.readConfig('dstHost'),
4746
username: this.readConfig('username'),
48-
localPort: srcPort,
49-
privateKey: this.readConfig('privateKeyPath')
47+
localPort: srcPort
5048
};
5149

52-
if (sshConfig.privateKey) {
53-
sshConfig.privateKey = fs.readFileSync(untildify(sshConfig.privateKey));
54-
}
55-
50+
var password = this.readConfig('password');
51+
var privateKey = this.readConfig('privateKeyPath');
5652
var tunnel = this.readConfig('tunnelClient');
5753

58-
return new Promise(function (resolve, reject) {
59-
var sshTunnel = tunnel(sshConfig, function (error /*, result */) {
54+
if (password) {
55+
sshConfig.password = password;
56+
} else if (privateKey) {
57+
sshConfig.privateKey = fs.readFileSync(untildify(privateKey));
58+
}
59+
60+
return new Promise(function(resolve, reject) {
61+
var sshTunnel = tunnel(sshConfig, function(error /*, result */) {
6062
if (error) {
6163
reject(error);
6264
} else {

tests/.jshintrc

+7-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@
2121
"andThen",
2222
"currentURL",
2323
"currentPath",
24-
"currentRouteName"
24+
"currentRouteName",
25+
"require",
26+
"describe",
27+
"before",
28+
"beforeEach",
29+
"it",
30+
"process"
2531
],
2632
"node": false,
2733
"browser": false,

tests/runner.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/*jshint globalstrict: true*/
12
'use strict';
23

34
var glob = require('glob');

tests/unit/index-nodetest.js

+64-21
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1+
/*jshint globalstrict: true*/
12
'use strict';
23

3-
var Promise = require('ember-cli/lib/ext/promise');
44
var assert = require('ember-cli/tests/helpers/assert');
5-
var fs = require('fs');
6-
var path = require('path');
75

86
describe('ssh-tunnel plugin', function() {
97
var subject, mockUi;
@@ -15,7 +13,8 @@ describe('ssh-tunnel plugin', function() {
1513
write: function() { },
1614
writeLine: function(message) {
1715
this.messages.push(message);
18-
}
16+
},
17+
verbose: true
1918
};
2019
});
2120

@@ -60,7 +59,7 @@ describe('ssh-tunnel plugin', function() {
6059
assert.ok(true); // it didn't throw
6160
});
6261

63-
describe('without providing config', function () {
62+
describe('without providing config', function() {
6463
var plugin, context, config;
6564

6665
beforeEach(function() {
@@ -70,20 +69,19 @@ describe('ssh-tunnel plugin', function() {
7069
});
7170

7271
it('raises about missing required config', function() {
73-
config = { };
72+
config = {};
7473
context = {
7574
ui: mockUi,
7675
config: config
7776
};
7877
plugin.beforeHook(context);
79-
assert.throws(function(error){
78+
assert.throws(function(){
8079
plugin.configure(context);
8180
});
8281
var messages = mockUi.messages.reduce(function(previous, current) {
8382
if (/- Missing required config:\s.*/.test(current)) {
84-
previous.push(current);
83+
previous.push(current);
8584
}
86-
8785
return previous;
8886
}, []);
8987
assert.equal(messages.length, 1);
@@ -108,33 +106,79 @@ previous.push(current);
108106

109107
return previous;
110108
}, []);
111-
assert.equal(messages.length, 5);
109+
assert.equal(messages.length, 4);
112110
});
113111

114112
it('adds default config to the config object', function() {
113+
config = {
114+
'ssh-tunnel': {
115+
host: 'example.com',
116+
username: 'ghedamat'
117+
}
118+
};
115119
context = {
116120
ui: mockUi,
117-
config: {
118-
'ssh-tunnel': {
119-
host: 'example.com',
120-
username: 'ghedamat'
121-
}
122-
}
121+
config: config
123122
};
124123
plugin.beforeHook(context);
125124
plugin.configure(context);
126125
assert.isDefined(config['ssh-tunnel'].dstPort);
127126
assert.isDefined(config['ssh-tunnel'].dstHost);
128127
assert.isDefined(config['ssh-tunnel'].srcPort);
129128
assert.isDefined(config['ssh-tunnel'].tunnelClient);
129+
});
130+
});
131+
132+
describe('with custom authentication provided', function () {
133+
var plugin, context, config;
134+
135+
beforeEach(function() {
136+
plugin = subject.createDeployPlugin({
137+
name: 'ssh-tunnel'
138+
});
139+
});
140+
141+
it('uses a password', function() {
142+
config = {
143+
'ssh-tunnel': {
144+
host: 'example.com',
145+
username: 'example',
146+
password: 'secret'
147+
}
148+
};
149+
context = {
150+
ui: mockUi,
151+
config: config
152+
};
153+
plugin.beforeHook(context);
154+
plugin.configure(context);
155+
assert.isDefined(config['ssh-tunnel'].password);
156+
assert.isUndefined(config['ssh-tunnel'].privateKeyPath);
157+
});
158+
159+
it('uses a key path', function() {
160+
config = {
161+
'ssh-tunnel': {
162+
host: 'example.com',
163+
username: 'example',
164+
privateKeyPath: '~/.ssh/id_rsa'
165+
}
166+
};
167+
context = {
168+
ui: mockUi,
169+
config: config
170+
};
171+
plugin.beforeHook(context);
172+
plugin.configure(context);
173+
assert.isUndefined(config['ssh-tunnel'].password);
130174
assert.isDefined(config['ssh-tunnel'].privateKeyPath);
175+
assert.equal(config['ssh-tunnel'].privateKeyPath, '~/.ssh/id_rsa');
131176
});
132177
});
133178
});
134179

135180
describe('setup hook', function() {
136-
var plugin;
137-
var context;
181+
var plugin, context;
138182

139183
beforeEach(function() {
140184
plugin = subject.createDeployPlugin({
@@ -175,8 +219,7 @@ previous.push(current);
175219
});
176220

177221
describe('teardown hook', function() {
178-
var plugin;
179-
var context;
222+
var plugin, context;
180223

181224
beforeEach(function() {
182225
plugin = subject.createDeployPlugin({
@@ -203,7 +246,7 @@ previous.push(current);
203246
}
204247
};
205248

206-
var result = plugin.teardown(context);
249+
plugin.teardown(context);
207250
});
208251
});
209252
});

0 commit comments

Comments
 (0)