aptible-cli 0.11.2 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/README.md +1 -0
- data/lib/aptible/cli/helpers/database.rb +2 -2
- data/lib/aptible/cli/subcommands/db.rb +11 -1
- data/lib/aptible/cli/subcommands/ssh.rb +15 -15
- data/lib/aptible/cli/version.rb +1 -1
- data/spec/aptible/cli/agent_spec.rb +17 -13
- data/spec/aptible/cli/subcommands/apps_spec.rb +16 -14
- data/spec/aptible/cli/subcommands/db_spec.rb +60 -10
- data/spec/aptible/cli/subcommands/deploy_spec.rb +2 -2
- data/spec/aptible/cli/subcommands/domains_spec.rb +5 -3
- data/spec/aptible/cli/subcommands/logs_spec.rb +5 -3
- data/spec/aptible/cli/subcommands/ssh_spec.rb +27 -4
- data/spec/mock/ssh +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: daac13a8f95ed0d51f55b1facdaf8fb7d6777253
|
4
|
+
data.tar.gz: 289c5c14b294a2bc47ed05c6c51bd6dedcc8fb9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53d1ff2a1fd3987bf053c8779679eee38a369a1a0f39ed93e7880335d486e81f0ece0991e652276aab01554b1f3cb9eba4a3a794c74894cac9dd122b148ab1cb
|
7
|
+
data.tar.gz: 4e813f1040e3677a3a96f14c3788b6ba3564443e370bbec606ca7c3e5b9f9a9fc65fc53a078ae43cddea6496dd0b25f7ded2981d943abcfbf13f41430db5cba4
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -50,6 +50,7 @@ Commands:
|
|
50
50
|
aptible db:reload HANDLE # Reload a database
|
51
51
|
aptible db:restart HANDLE [--container-size SIZE_MB] [--size SIZE_GB] # Restart a database
|
52
52
|
aptible db:tunnel HANDLE # Create a local tunnel to a database
|
53
|
+
aptible db:url HANDLE # Display a database URL
|
53
54
|
aptible deploy [OPTIONS] [VAR1=VAL1] [VAR=VAL2] ... # Deploy an app
|
54
55
|
aptible domains # Print an app's current virtual domains
|
55
56
|
aptible help [COMMAND] # Describe available commands or one specific command
|
@@ -78,7 +78,7 @@ module Aptible
|
|
78
78
|
raise Thor::Error, 'This command only works for PostgreSQL'
|
79
79
|
end
|
80
80
|
|
81
|
-
credential =
|
81
|
+
credential = find_credential(database)
|
82
82
|
|
83
83
|
with_local_tunnel(credential) do |tunnel_helper|
|
84
84
|
yield local_url(credential, tunnel_helper.port)
|
@@ -93,7 +93,7 @@ module Aptible
|
|
93
93
|
"localhost.aptible.in:#{local_port}#{uri.path}"
|
94
94
|
end
|
95
95
|
|
96
|
-
def
|
96
|
+
def find_credential(database, type = nil)
|
97
97
|
unless database.provisioned?
|
98
98
|
raise Thor::Error, "Database #{database.handle} is not provisioned"
|
99
99
|
end
|
@@ -95,7 +95,7 @@ module Aptible
|
|
95
95
|
desired_port = Integer(options[:port] || 0)
|
96
96
|
database = ensure_database(options.merge(db: handle))
|
97
97
|
|
98
|
-
credential =
|
98
|
+
credential = find_credential(database, options[:type])
|
99
99
|
|
100
100
|
say "Creating #{credential.type} tunnel to #{database.handle}...",
|
101
101
|
:green
|
@@ -177,6 +177,16 @@ module Aptible
|
|
177
177
|
op = database.create_operation!(opts)
|
178
178
|
attach_to_operation_logs(op)
|
179
179
|
end
|
180
|
+
|
181
|
+
desc 'db:url HANDLE', 'Display a database URL'
|
182
|
+
option :environment
|
183
|
+
option :type, type: :string
|
184
|
+
define_method 'db:url' do |handle|
|
185
|
+
database = ensure_database(options.merge(db: handle))
|
186
|
+
credential = find_credential(database, options[:type])
|
187
|
+
|
188
|
+
say(credential.connection_url)
|
189
|
+
end
|
180
190
|
end
|
181
191
|
end
|
182
192
|
end
|
@@ -20,13 +20,6 @@ module Aptible
|
|
20
20
|
def ssh(*args)
|
21
21
|
app = ensure_app(options)
|
22
22
|
|
23
|
-
op = app.create_operation!(type: 'execute',
|
24
|
-
command: command_from_args(*args),
|
25
|
-
status: 'succeeded')
|
26
|
-
|
27
|
-
ENV['ACCESS_TOKEN'] = fetch_token
|
28
|
-
opts = ['-o', 'SendEnv=ACCESS_TOKEN']
|
29
|
-
|
30
23
|
# SSH's default behavior is as follows:
|
31
24
|
#
|
32
25
|
# - If a TTY is forced, one is allocated.
|
@@ -48,15 +41,22 @@ module Aptible
|
|
48
41
|
#
|
49
42
|
# End users can always override this behavior with the
|
50
43
|
# --force-tty option.
|
51
|
-
tty_mode = if options[:force_tty]
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
opts << tty_mode
|
44
|
+
tty_mode, interactive = if options[:force_tty]
|
45
|
+
['-tt', true]
|
46
|
+
elsif [STDIN, STDOUT].all?(&:tty?)
|
47
|
+
['-t', true]
|
48
|
+
else
|
49
|
+
['-T', false]
|
50
|
+
end
|
59
51
|
|
52
|
+
op = app.create_operation!(
|
53
|
+
type: 'execute',
|
54
|
+
command: command_from_args(*args),
|
55
|
+
interactive: interactive
|
56
|
+
)
|
57
|
+
|
58
|
+
ENV['ACCESS_TOKEN'] = fetch_token
|
59
|
+
opts = ['-o', 'SendEnv=ACCESS_TOKEN', tty_mode]
|
60
60
|
exit_with_ssh_portal(op, *opts)
|
61
61
|
end
|
62
62
|
|
data/lib/aptible/cli/version.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Aptible::CLI::Agent do
|
4
|
-
before
|
5
|
-
|
6
|
-
|
4
|
+
before do
|
5
|
+
allow(subject).to receive(:ask)
|
6
|
+
allow(subject).to receive(:save_token)
|
7
|
+
allow(subject).to receive(:token_file).and_return 'some.json'
|
8
|
+
end
|
7
9
|
|
8
10
|
describe '#version' do
|
9
11
|
it 'should print the version' do
|
@@ -32,20 +34,21 @@ describe Aptible::CLI::Agent do
|
|
32
34
|
before do
|
33
35
|
m = -> (code) { @code = code }
|
34
36
|
OAuth2::Error.send :define_method, :initialize, m
|
37
|
+
|
38
|
+
allow(token).to receive(:access_token).and_return 'access_token'
|
39
|
+
allow(token).to receive(:created_at).and_return created_at
|
40
|
+
allow(token).to receive(:expires_at).and_return expires_at
|
41
|
+
allow(subject).to receive(:puts) { |v| output << v }
|
35
42
|
end
|
36
|
-
before { token.stub(:access_token) { 'access_token' } }
|
37
|
-
before { token.stub(:created_at) { created_at } }
|
38
|
-
before { token.stub(:expires_at) { expires_at } }
|
39
|
-
before { allow(subject).to receive(:puts) { |m| output << m } }
|
40
43
|
|
41
44
|
it 'should save a token to ~/.aptible/tokens' do
|
42
|
-
Aptible::Auth::Token.
|
45
|
+
allow(Aptible::Auth::Token).to receive(:create).and_return token
|
43
46
|
expect(subject).to receive(:save_token).with('access_token')
|
44
47
|
subject.login
|
45
48
|
end
|
46
49
|
|
47
50
|
it 'should output the token location and token lifetime' do
|
48
|
-
Aptible::Auth::Token.
|
51
|
+
allow(Aptible::Auth::Token).to receive(:create).and_return token
|
49
52
|
subject.login
|
50
53
|
expect(output.size).to eq(3)
|
51
54
|
expect(output[0]).to eq('')
|
@@ -54,7 +57,8 @@ describe Aptible::CLI::Agent do
|
|
54
57
|
end
|
55
58
|
|
56
59
|
it 'should raise an error if authentication fails' do
|
57
|
-
Aptible::Auth::Token.
|
60
|
+
allow(Aptible::Auth::Token).to receive(:create)
|
61
|
+
.and_raise(OAuth2::Error, 'foo')
|
58
62
|
expect do
|
59
63
|
subject.login
|
60
64
|
end.to raise_error 'Could not authenticate with given credentials: foo'
|
@@ -63,7 +67,7 @@ describe Aptible::CLI::Agent do
|
|
63
67
|
it 'should use command line arguments if passed' do
|
64
68
|
options = { email: 'test@example.com', password: 'password',
|
65
69
|
lifetime: '30 minutes' }
|
66
|
-
subject.
|
70
|
+
allow(subject).to receive(:options).and_return options
|
67
71
|
args = { email: options[:email], password: options[:password],
|
68
72
|
expires_in: 30.minutes.seconds }
|
69
73
|
expect(Aptible::Auth::Token).to receive(:create).with(args) { token }
|
@@ -72,7 +76,7 @@ describe Aptible::CLI::Agent do
|
|
72
76
|
|
73
77
|
it 'should default to 1 week expiry when OTP is disabled' do
|
74
78
|
options = { email: 'test@example.com', password: 'password' }
|
75
|
-
subject.
|
79
|
+
allow(subject).to receive(:options).and_return options
|
76
80
|
args = options.dup.merge(expires_in: 1.week.seconds)
|
77
81
|
expect(Aptible::Auth::Token).to receive(:create).with(args) { token }
|
78
82
|
subject.login
|
@@ -81,7 +85,7 @@ describe Aptible::CLI::Agent do
|
|
81
85
|
it 'should fail if the lifetime is invalid' do
|
82
86
|
options = { email: 'test@example.com', password: 'password',
|
83
87
|
lifetime: 'this is sparta' }
|
84
|
-
subject.
|
88
|
+
allow(subject).to receive(:options).and_return options
|
85
89
|
|
86
90
|
expect { subject.login }.to raise_error(/Invalid token lifetime/)
|
87
91
|
end
|
@@ -17,10 +17,12 @@ def dummy_strategy_factory(app_handle, env_handle, usable,
|
|
17
17
|
end
|
18
18
|
|
19
19
|
describe Aptible::CLI::Agent do
|
20
|
-
before
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
before do
|
21
|
+
allow(subject).to receive(:ask)
|
22
|
+
allow(subject).to receive(:save_token)
|
23
|
+
allow(subject).to receive(:attach_to_operation_logs)
|
24
|
+
allow(subject).to receive(:fetch_token) { double 'token' }
|
25
|
+
end
|
24
26
|
|
25
27
|
let!(:account) { Fabricate(:account) }
|
26
28
|
let!(:app) { Fabricate(:app, handle: 'hello', account: account) }
|
@@ -196,14 +198,14 @@ describe Aptible::CLI::Agent do
|
|
196
198
|
describe '#ensure_app' do
|
197
199
|
it 'fails if no usable strategy is found' do
|
198
200
|
strategies = [dummy_strategy_factory(nil, nil, false)]
|
199
|
-
subject.
|
201
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
200
202
|
|
201
203
|
expect { subject.ensure_app }.to raise_error(/Could not find app/)
|
202
204
|
end
|
203
205
|
|
204
206
|
it 'fails if an environment is specified but not found' do
|
205
207
|
strategies = [dummy_strategy_factory('hello', 'aptible', true)]
|
206
|
-
subject.
|
208
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
207
209
|
|
208
210
|
expect(subject).to receive(:environment_from_handle).and_return(nil)
|
209
211
|
|
@@ -220,7 +222,7 @@ describe Aptible::CLI::Agent do
|
|
220
222
|
|
221
223
|
it 'scopes the app search to an environment if provided' do
|
222
224
|
strategies = [dummy_strategy_factory('hello', 'aptible', true)]
|
223
|
-
subject.
|
225
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
224
226
|
|
225
227
|
expect(subject).to receive(:environment_from_handle).with('aptible')
|
226
228
|
.and_return(account)
|
@@ -230,7 +232,7 @@ describe Aptible::CLI::Agent do
|
|
230
232
|
|
231
233
|
it 'does not scope the app search to an environment if not provided' do
|
232
234
|
strategies = [dummy_strategy_factory('hello', nil, true)]
|
233
|
-
subject.
|
235
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
234
236
|
|
235
237
|
expect(subject.ensure_app).to eq(apps.first)
|
236
238
|
end
|
@@ -239,7 +241,7 @@ describe Aptible::CLI::Agent do
|
|
239
241
|
apps.pop
|
240
242
|
|
241
243
|
strategies = [dummy_strategy_factory('hello', nil, true)]
|
242
|
-
subject.
|
244
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
243
245
|
|
244
246
|
expect { subject.ensure_app }.to raise_error(/not find app hello/)
|
245
247
|
end
|
@@ -248,7 +250,7 @@ describe Aptible::CLI::Agent do
|
|
248
250
|
apps.pop
|
249
251
|
|
250
252
|
strategies = [dummy_strategy_factory('hello', nil, true)]
|
251
|
-
subject.
|
253
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
252
254
|
|
253
255
|
expect { subject.ensure_app }.to raise_error(/from dummy/)
|
254
256
|
end
|
@@ -257,7 +259,7 @@ describe Aptible::CLI::Agent do
|
|
257
259
|
apps.pop
|
258
260
|
|
259
261
|
strategies = [dummy_strategy_factory('hello', 'aptible', true)]
|
260
|
-
subject.
|
262
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
261
263
|
|
262
264
|
expect(subject).to receive(:environment_from_handle).with('aptible')
|
263
265
|
.and_return(account)
|
@@ -269,7 +271,7 @@ describe Aptible::CLI::Agent do
|
|
269
271
|
apps << Fabricate(:app, handle: 'hello')
|
270
272
|
|
271
273
|
strategies = [dummy_strategy_factory('hello', nil, true)]
|
272
|
-
subject.
|
274
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
273
275
|
|
274
276
|
expect { subject.ensure_app }.to raise_error(/Multiple apps/)
|
275
277
|
end
|
@@ -279,7 +281,7 @@ describe Aptible::CLI::Agent do
|
|
279
281
|
dummy_strategy_factory('hello', nil, false),
|
280
282
|
dummy_strategy_factory('hello', nil, true)
|
281
283
|
]
|
282
|
-
subject.
|
284
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
283
285
|
|
284
286
|
expect(subject.ensure_app).to eq(apps.first)
|
285
287
|
end
|
@@ -287,7 +289,7 @@ describe Aptible::CLI::Agent do
|
|
287
289
|
it 'passes options to the strategy' do
|
288
290
|
receiver = []
|
289
291
|
strategies = [dummy_strategy_factory('hello', nil, false, receiver)]
|
290
|
-
subject.
|
292
|
+
allow(subject).to receive(:handle_strategies) { strategies }
|
291
293
|
|
292
294
|
options = { app: 'foo', environment: 'bar' }
|
293
295
|
expect { subject.ensure_app options }.to raise_error(/not find app/)
|
@@ -4,9 +4,11 @@ class SocatHelperMock < OpenStruct
|
|
4
4
|
end
|
5
5
|
|
6
6
|
describe Aptible::CLI::Agent do
|
7
|
-
before
|
8
|
-
|
9
|
-
|
7
|
+
before do
|
8
|
+
allow(subject).to receive(:ask)
|
9
|
+
allow(subject).to receive(:save_token)
|
10
|
+
allow(subject).to receive(:fetch_token) { double 'token' }
|
11
|
+
end
|
10
12
|
|
11
13
|
let(:handle) { 'foobar' }
|
12
14
|
let(:database) { Fabricate(:database, handle: handle) }
|
@@ -20,7 +22,7 @@ describe Aptible::CLI::Agent do
|
|
20
22
|
before do
|
21
23
|
allow(Aptible::Api::Account).to receive(:all).and_return([account])
|
22
24
|
allow(db).to receive(:reload).and_return(db)
|
23
|
-
op.
|
25
|
+
allow(op).to receive(:errors).and_return(Aptible::Resource::Errors.new)
|
24
26
|
end
|
25
27
|
|
26
28
|
it 'creates a new DB' do
|
@@ -163,15 +165,17 @@ describe Aptible::CLI::Agent do
|
|
163
165
|
end
|
164
166
|
|
165
167
|
it 'fails when the database is not provisioned' do
|
166
|
-
database.
|
168
|
+
allow(database).to receive(:status) { 'pending' }
|
167
169
|
|
168
170
|
expect { subject.send('db:tunnel', handle) }
|
169
171
|
.to raise_error(/foobar is not provisioned/im)
|
170
172
|
end
|
171
173
|
|
172
174
|
context 'v1 stack' do
|
173
|
-
before
|
174
|
-
|
175
|
+
before do
|
176
|
+
allow(database.account.stack).to receive(:version) { 'v1' }
|
177
|
+
allow(subject).to receive(:say)
|
178
|
+
end
|
175
179
|
|
176
180
|
it 'falls back to the database itself if no type is given' do
|
177
181
|
expect(subject).to receive(:with_local_tunnel).with(database, 0)
|
@@ -180,7 +184,7 @@ describe Aptible::CLI::Agent do
|
|
180
184
|
|
181
185
|
it 'falls back to the database itself if type matches' do
|
182
186
|
subject.options = { type: 'bar' }
|
183
|
-
database.
|
187
|
+
allow(database).to receive(:type) { 'bar' }
|
184
188
|
|
185
189
|
expect(subject).to receive(:with_local_tunnel).with(database, 0)
|
186
190
|
subject.send('db:tunnel', handle)
|
@@ -188,7 +192,7 @@ describe Aptible::CLI::Agent do
|
|
188
192
|
|
189
193
|
it 'does not fall back to the database itself if type mismatches' do
|
190
194
|
subject.options = { type: 'bar' }
|
191
|
-
database.
|
195
|
+
allow(database).to receive(:type) { 'foo' }
|
192
196
|
|
193
197
|
expect { subject.send('db:tunnel', handle) }
|
194
198
|
.to raise_error(/no credential with type bar/im)
|
@@ -218,7 +222,7 @@ describe Aptible::CLI::Agent do
|
|
218
222
|
end
|
219
223
|
|
220
224
|
token = 'the-token'
|
221
|
-
allow(subject).to receive(:fetch_token)
|
225
|
+
allow(subject).to receive(:fetch_token) { token }
|
222
226
|
allow(Aptible::Api::Account).to receive(:all).with(token: token)
|
223
227
|
.and_return([staging, prod])
|
224
228
|
end
|
@@ -353,4 +357,50 @@ describe Aptible::CLI::Agent do
|
|
353
357
|
.to raise_error(Thor::Error, 'Could not find database nope')
|
354
358
|
end
|
355
359
|
end
|
360
|
+
|
361
|
+
describe '#db:url' do
|
362
|
+
let(:databases) { [database] }
|
363
|
+
before { expect(Aptible::Api::Database).to receive(:all) { databases } }
|
364
|
+
|
365
|
+
it 'fails if the DB is not found' do
|
366
|
+
expect { subject.send('db:url', 'nope') }
|
367
|
+
.to raise_error(Thor::Error, 'Could not find database nope')
|
368
|
+
end
|
369
|
+
|
370
|
+
context 'valid database' do
|
371
|
+
it 'returns the URL of a specified DB' do
|
372
|
+
cred = Fabricate(:database_credential, default: true, type: 'foo',
|
373
|
+
database: database)
|
374
|
+
|
375
|
+
expect(subject).to receive(:say).with(cred.connection_url)
|
376
|
+
expect(database).not_to receive(:connection_url)
|
377
|
+
|
378
|
+
subject.send('db:url', handle)
|
379
|
+
end
|
380
|
+
|
381
|
+
it 'fails if multiple DBs are found' do
|
382
|
+
databases << database
|
383
|
+
|
384
|
+
expect { subject.send('db:url', handle) }
|
385
|
+
.to raise_error(/Multiple databases/)
|
386
|
+
end
|
387
|
+
|
388
|
+
context 'v1 stack' do
|
389
|
+
before do
|
390
|
+
allow(database.account.stack).to receive(:version) { 'v1' }
|
391
|
+
allow(subject).to receive(:say)
|
392
|
+
end
|
393
|
+
|
394
|
+
it 'returns the URL of a specified DB' do
|
395
|
+
connection_url = 'postgresql://aptible-v1:password@lega.cy:4242/db'
|
396
|
+
|
397
|
+
expect(subject).to receive(:say).with(connection_url)
|
398
|
+
expect(database).to receive(:connection_url)
|
399
|
+
.and_return(connection_url)
|
400
|
+
|
401
|
+
subject.send('db:url', handle)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
356
406
|
end
|
@@ -9,7 +9,7 @@ describe Aptible::CLI::Agent do
|
|
9
9
|
before do
|
10
10
|
allow(Aptible::Api::App).to receive(:all) { [app] }
|
11
11
|
allow(Aptible::Api::Account).to receive(:all) { [account] }
|
12
|
-
subject.
|
12
|
+
allow(subject).to receive(:fetch_token) { double'token' }
|
13
13
|
end
|
14
14
|
|
15
15
|
context 'with app' do
|
@@ -148,7 +148,7 @@ describe Aptible::CLI::Agent do
|
|
148
148
|
it 'does not allow deploying nothing on an unprovisioned app' do
|
149
149
|
stub_options
|
150
150
|
|
151
|
-
app.
|
151
|
+
allow(app).to receive(:status) { 'pending' }
|
152
152
|
|
153
153
|
expect { subject.deploy }
|
154
154
|
.to raise_error(/either from git.*docker/im)
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Aptible::CLI::Agent do
|
4
|
-
before
|
5
|
-
|
6
|
-
|
4
|
+
before do
|
5
|
+
allow(subject).to receive(:ask)
|
6
|
+
allow(subject).to receive(:save_token)
|
7
|
+
allow(subject).to receive(:fetch_token) { double 'token' }
|
8
|
+
end
|
7
9
|
|
8
10
|
let!(:account) { Fabricate(:account) }
|
9
11
|
let!(:app) { Fabricate(:app, handle: 'hello', account: account) }
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Aptible::CLI::Agent do
|
4
|
-
before
|
5
|
-
|
6
|
-
|
4
|
+
before do
|
5
|
+
allow(subject).to receive(:ask)
|
6
|
+
allow(subject).to receive(:save_token)
|
7
|
+
allow(subject).to receive(:fetch_token) { 'some token' }
|
8
|
+
end
|
7
9
|
|
8
10
|
let(:app) { Fabricate(:app, handle: 'foo') }
|
9
11
|
let(:database) { Fabricate(:database, handle: 'bar', status: 'provisioned') }
|
@@ -6,22 +6,25 @@ describe Aptible::CLI::Agent do
|
|
6
6
|
let(:operation) { double('operation') }
|
7
7
|
|
8
8
|
context 'TTY control' do
|
9
|
+
let(:args) { { type: 'execute', command: '/bin/bash' } }
|
10
|
+
|
9
11
|
before do
|
10
12
|
expect(subject).to receive(:ensure_app).and_return(app)
|
11
13
|
expect(subject).to receive(:fetch_token).and_return('some token')
|
12
|
-
|
13
|
-
expect(app).to receive(:create_operation!).with(
|
14
|
-
type: 'execute', command: '/bin/bash', status: 'succeeded'
|
15
|
-
).and_return(operation)
|
16
14
|
end
|
17
15
|
|
18
16
|
it 'allocates a TTY if STDIN and STDOUT are TTYs' do
|
19
17
|
allow(STDIN).to receive(:tty?).and_return(true)
|
20
18
|
allow(STDOUT).to receive(:tty?).and_return(true)
|
21
19
|
|
20
|
+
expect(app).to receive(:create_operation!).with(
|
21
|
+
**args, interactive: true
|
22
|
+
).and_return(operation)
|
23
|
+
|
22
24
|
expect(subject).to receive(:exit_with_ssh_portal).with(
|
23
25
|
operation, '-o', 'SendEnv=ACCESS_TOKEN', '-t'
|
24
26
|
)
|
27
|
+
|
25
28
|
subject.ssh
|
26
29
|
end
|
27
30
|
|
@@ -30,9 +33,14 @@ describe Aptible::CLI::Agent do
|
|
30
33
|
allow(STDOUT).to receive(:tty?).and_return(true)
|
31
34
|
allow(STDERR).to receive(:tty?).and_return(false)
|
32
35
|
|
36
|
+
expect(app).to receive(:create_operation!).with(
|
37
|
+
**args, interactive: true
|
38
|
+
).and_return(operation)
|
39
|
+
|
33
40
|
expect(subject).to receive(:exit_with_ssh_portal).with(
|
34
41
|
operation, '-o', 'SendEnv=ACCESS_TOKEN', '-t'
|
35
42
|
)
|
43
|
+
|
36
44
|
subject.ssh
|
37
45
|
end
|
38
46
|
|
@@ -40,9 +48,14 @@ describe Aptible::CLI::Agent do
|
|
40
48
|
allow(STDIN).to receive(:tty?).and_return(false)
|
41
49
|
allow(STDOUT).to receive(:tty?).and_return(true)
|
42
50
|
|
51
|
+
expect(app).to receive(:create_operation!).with(
|
52
|
+
**args, interactive: false
|
53
|
+
).and_return(operation)
|
54
|
+
|
43
55
|
expect(subject).to receive(:exit_with_ssh_portal).with(
|
44
56
|
operation, '-o', 'SendEnv=ACCESS_TOKEN', '-T'
|
45
57
|
)
|
58
|
+
|
46
59
|
subject.ssh
|
47
60
|
end
|
48
61
|
|
@@ -50,9 +63,14 @@ describe Aptible::CLI::Agent do
|
|
50
63
|
allow(STDIN).to receive(:tty?).and_return(true)
|
51
64
|
allow(STDOUT).to receive(:tty?).and_return(false)
|
52
65
|
|
66
|
+
expect(app).to receive(:create_operation!).with(
|
67
|
+
**args, interactive: false
|
68
|
+
).and_return(operation)
|
69
|
+
|
53
70
|
expect(subject).to receive(:exit_with_ssh_portal).with(
|
54
71
|
operation, '-o', 'SendEnv=ACCESS_TOKEN', '-T'
|
55
72
|
)
|
73
|
+
|
56
74
|
subject.ssh
|
57
75
|
end
|
58
76
|
|
@@ -62,9 +80,14 @@ describe Aptible::CLI::Agent do
|
|
62
80
|
allow(STDIN).to receive(:tty?).and_return(false)
|
63
81
|
allow(STDOUT).to receive(:tty?).and_return(false)
|
64
82
|
|
83
|
+
expect(app).to receive(:create_operation!).with(
|
84
|
+
**args, interactive: true
|
85
|
+
).and_return(operation)
|
86
|
+
|
65
87
|
expect(subject).to receive(:exit_with_ssh_portal).with(
|
66
88
|
operation, '-o', 'SendEnv=ACCESS_TOKEN', '-tt'
|
67
89
|
)
|
90
|
+
|
68
91
|
subject.ssh
|
69
92
|
end
|
70
93
|
end
|
data/spec/mock/ssh
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ssh_mock.rb
|
1
|
+
spec/mock/ssh_mock.rb
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aptible-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Macreery
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aptible-resource
|
@@ -306,7 +306,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
306
306
|
version: '0'
|
307
307
|
requirements: []
|
308
308
|
rubyforge_project:
|
309
|
-
rubygems_version: 2.
|
309
|
+
rubygems_version: 2.6.13
|
310
310
|
signing_key:
|
311
311
|
specification_version: 4
|
312
312
|
summary: Command-line interface for Aptible services
|