aptible-cli 0.26.4 → 0.26.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c756f930a26ab5b060f01270b80c9ec2963c8f739be4ffcd2a5d56e9dac2860
4
- data.tar.gz: 55fdde5cde257bd36c6c16a17e7f639745f85947b1cf40269c0d73ab0093615c
3
+ metadata.gz: 13c94bbbfe4b853700fec4e895ab0eebd02f0c5ffcddf6cfd0a597c42f665d37
4
+ data.tar.gz: c495f4582ca15271799caa1b71a3922c3e5bbaafa692eda9476862465971556e
5
5
  SHA512:
6
- metadata.gz: 01122dab06813f9b67100c11e6e59ec6942f5263340efc26bbf73440b51c39c7cd0be7258b987fa39056092b29bf181ded4d14423d27ff795cd18bf85b97fe96
7
- data.tar.gz: d7ed67882c43c958dcc60c7ef5ba518f3eb6ad72ca014f4c0b761478f2748054af64286aca26b8ac97b5ca5ea03964bc34fd422d3cf42f4996b4c6949815d870
6
+ metadata.gz: eb5b9e8adc78ba955f5125ca6c673894fea37fb8dd9a61775b4f44f87b9afc2c7fd9dbf8c645cd380af6fca7f754f03654a139539d9180060c6475544320b864
7
+ data.tar.gz: d86d87bb3c7d8dd6c57692c63c0592b99f950cd96b8b6bce1038678678a0c983c6b734ef380852b6edb8bb1e4e205fa6938b5045c8d5337f82fd4c40fb5aac2e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- aptible-cli (0.26.4)
4
+ aptible-cli (0.26.5)
5
5
  activesupport (>= 4.0, < 6.0)
6
6
  aptible-api (~> 1.12)
7
7
  aptible-auth (~> 1.4)
@@ -110,12 +110,9 @@ module Aptible
110
110
  end
111
111
  end
112
112
 
113
- apps = apps_from_handle(s.app_handle, environment)
113
+ app = app_from_handle(s.app_handle, environment)
114
114
 
115
- case apps.count
116
- when 1
117
- return apps.first
118
- when 0
115
+ if app.nil?
119
116
  err_bits = ['Could not find app', s.app_handle]
120
117
  if environment
121
118
  err_bits << 'in environment'
@@ -125,11 +122,9 @@ module Aptible
125
122
  end
126
123
  err_bits << s.explain
127
124
  raise Thor::Error, err_bits.join(' ')
128
- else
129
- err = "Multiple apps named #{s.app_handle} exist, please specify " \
130
- 'with --environment'
131
- raise Thor::Error, err
132
125
  end
126
+
127
+ app
133
128
  end
134
129
 
135
130
  def ensure_service(options, type)
@@ -166,13 +161,20 @@ module Aptible
166
161
  )
167
162
  end
168
163
 
169
- def apps_from_handle(handle, environment)
170
- # TODO: This should probably use each_app for more efficiency.
171
- if environment
172
- environment.apps
173
- else
174
- apps_all
175
- end.select { |a| a.handle == handle }
164
+ def app_from_handle(handle, environment)
165
+ url = "/find/app?handle=#{handle}"
166
+ url += "&environment=#{environment.handle}" unless environment.nil?
167
+
168
+ Aptible::Api::App.find_by_url(
169
+ url,
170
+ token: fetch_token
171
+ )
172
+ rescue HyperResource::ClientError => e
173
+ raise unless e.body.is_a?(Hash) &&
174
+ e.body['error'] == 'multiple_resources_found'
175
+ raise Thor::Error,
176
+ "Multiple apps named #{handle} exist, please specify " \
177
+ 'with --environment'
176
178
  end
177
179
 
178
180
  def extract_env(args)
@@ -36,16 +36,10 @@ module Aptible
36
36
  raise Thor::Error,
37
37
  "Could not find environment #{environment_handle}"
38
38
  end
39
- databases = databases_from_handle(db_handle, environment)
40
- case databases.count
41
- when 1
42
- return databases.first
43
- when 0
44
- raise Thor::Error, "Could not find database #{db_handle}"
45
- else
46
- err = 'Multiple databases exist, please specify with --environment'
47
- raise Thor::Error, err
48
- end
39
+ db = database_from_handle(db_handle, environment)
40
+ raise Thor::Error, "Could not find database #{db_handle}" if db.nil?
41
+
42
+ db
49
43
  end
50
44
 
51
45
  def databases_href
@@ -140,20 +134,27 @@ module Aptible
140
134
  external_rds_databases_all.find { |a| a.handle == handle }
141
135
  end
142
136
 
143
- def databases_from_handle(handle, environment)
144
- databases = if environment
145
- environment.databases
146
- else
147
- databases_all
148
- end
149
- databases.select { |a| a.handle == handle }
137
+ def database_from_handle(handle, environment)
138
+ url = "/find/database?handle=#{handle}"
139
+ url += "&environment=#{environment.handle}" unless environment.nil?
140
+
141
+ Aptible::Api::Database.find_by_url(
142
+ url,
143
+ token: fetch_token
144
+ )
145
+ rescue HyperResource::ClientError => e
146
+ raise unless e.body.is_a?(Hash) &&
147
+ e.body['error'] == 'multiple_resources_found'
148
+ raise Thor::Error,
149
+ 'Multiple databases exist, please specify ' \
150
+ 'with --environment'
150
151
  end
151
152
 
152
153
  def clone_database(source, dest_handle)
153
154
  op = source.create_operation!(type: 'clone', handle: dest_handle)
154
155
  attach_to_operation_logs(op)
155
156
 
156
- databases_from_handle(dest_handle, source.account).first
157
+ database_from_handle(dest_handle, source.account)
157
158
  end
158
159
 
159
160
  def replicate_database(source, dest_handle, options)
@@ -177,7 +178,7 @@ module Aptible
177
178
  op = source.create_operation!(replication_params)
178
179
  attach_to_operation_logs(op)
179
180
 
180
- replica = databases_from_handle(dest_handle, source.account).first
181
+ replica = database_from_handle(dest_handle, source.account)
181
182
  attach_to_operation_logs(replica.operations.last)
182
183
  replica
183
184
  end
@@ -42,10 +42,11 @@ module Aptible
42
42
 
43
43
  def environment_from_handle(handle)
44
44
  return nil unless handle
45
- href = environment_href
46
- Aptible::Api::Account.all(token: fetch_token, href: href).find do |a|
47
- a.handle == handle
48
- end
45
+
46
+ Aptible::Api::Account.find_by_url(
47
+ "/find/account?handle=#{handle}",
48
+ token: fetch_token
49
+ )
49
50
  end
50
51
 
51
52
  def environment_map(accounts)
@@ -67,7 +67,7 @@ module Aptible
67
67
 
68
68
  account = destination_account || backup.account
69
69
 
70
- database = databases_from_handle(handle, account).first
70
+ database = database_from_handle(handle, account)
71
71
  render_database(database, account)
72
72
  end
73
73
 
@@ -1,5 +1,5 @@
1
1
  module Aptible
2
2
  module CLI
3
- VERSION = '0.26.4'.freeze
3
+ VERSION = '0.26.5'.freeze
4
4
  end
5
5
  end
@@ -20,13 +20,17 @@ describe Aptible::CLI::Agent do
20
20
  before do
21
21
  allow(subject).to receive(:save_token)
22
22
  allow(subject).to receive(:attach_to_operation_logs)
23
- allow(subject).to receive(:fetch_token) { double 'token' }
23
+ allow(subject).to receive(:fetch_token) { token }
24
+ allow(Aptible::Api::Account).to receive(:find_by_url)
25
+ .with("/find/account?handle=#{account.handle}", token: token)
26
+ .and_return(account)
24
27
  end
25
28
 
26
29
  let!(:account) { Fabricate(:account) }
27
30
  let!(:app) { Fabricate(:app, handle: 'hello', account: account) }
28
31
  let!(:service) { Fabricate(:service, app: app, process_type: 'web') }
29
32
  let(:op) { Fabricate(:operation, status: 'succeeded', resource: app) }
33
+ let(:token) { double 'token' }
30
34
 
31
35
  describe '#apps' do
32
36
  it 'lists an app in an account' do
@@ -83,13 +87,14 @@ describe Aptible::CLI::Agent do
83
87
 
84
88
  it 'lists filters down to one account' do
85
89
  account2 = Fabricate(:account, handle: 'account2')
90
+ allow(Aptible::Api::Account).to receive(:find_by_url)
91
+ .with("/find/account?handle=#{account2.handle}", token: token)
92
+ .and_return(account2)
86
93
  app2 = Fabricate(:app, account: account2, handle: 'app2')
87
94
  allow(subject).to receive(:options)
88
95
  .and_return(environment: account2.handle)
89
96
  allow(Aptible::Api::App).to receive(:all).and_return([app2])
90
97
 
91
- allow(Aptible::Api::Account).to receive(:all)
92
- .and_return([account, account2])
93
98
  subject.send('apps')
94
99
 
95
100
  expect(captured_output_text)
@@ -215,8 +220,11 @@ describe Aptible::CLI::Agent do
215
220
 
216
221
  describe '#apps:rename' do
217
222
  before do
218
- allow(Aptible::Api::App).to receive(:all) { [app] }
219
- allow(Aptible::Api::Account).to receive(:all) { [account] }
223
+ allow(Aptible::Api::App).to receive(:find_by_url)
224
+ .and_return(nil)
225
+ allow(Aptible::Api::App).to receive(:find_by_url)
226
+ .with("/find/app?handle=#{app.handle}&environment=#{account.handle}", token: token)
227
+ .and_return(app)
220
228
  end
221
229
 
222
230
  before(:each) do
@@ -256,7 +264,6 @@ describe Aptible::CLI::Agent do
256
264
 
257
265
  describe '#apps:scale' do
258
266
  before do
259
- allow(Aptible::Api::App).to receive(:all) { [app] }
260
267
  allow(Aptible::Api::Account).to receive(:all) { [account] }
261
268
  end
262
269
 
@@ -268,9 +275,9 @@ describe Aptible::CLI::Agent do
268
275
  .with('foobar')
269
276
  .and_return(account)
270
277
 
271
- expect(subject).to receive(:apps_from_handle)
278
+ expect(subject).to receive(:app_from_handle)
272
279
  .with('hello', account)
273
- .and_return([app])
280
+ .and_return(app)
274
281
  end
275
282
 
276
283
  def stub_options(**opts)
@@ -330,7 +337,7 @@ describe Aptible::CLI::Agent do
330
337
  allow(subject).to receive(:options) do
331
338
  { environment: 'foo', app: 'web', container_count: 2 }
332
339
  end
333
- allow(Aptible::Api::Account).to receive(:all) { [] }
340
+ allow(Aptible::Api::Account).to receive(:find_by_url).and_return(nil)
334
341
  allow(service).to receive(:create_operation!) { op }
335
342
 
336
343
  expect do
@@ -394,7 +401,14 @@ describe Aptible::CLI::Agent do
394
401
 
395
402
  before do
396
403
  account.apps = apps
397
- allow(Aptible::Api::App).to receive(:all).and_return(apps)
404
+ allow(Aptible::Api::App).to receive(:find_by_url)
405
+ .and_return(nil)
406
+ allow(Aptible::Api::App).to receive(:find_by_url)
407
+ .with("/find/app?handle=#{app.handle}&environment=#{account.handle}", token: token)
408
+ .and_return(app)
409
+ allow(Aptible::Api::App).to receive(:find_by_url)
410
+ .with("/find/app?handle=#{app.handle}", token: token)
411
+ .and_return(app)
398
412
  end
399
413
 
400
414
  it 'scopes the app search to an environment if provided' do
@@ -415,27 +429,21 @@ describe Aptible::CLI::Agent do
415
429
  end
416
430
 
417
431
  it 'fails if no app is found' do
418
- apps.pop
419
-
420
- strategies = [dummy_strategy_factory('hello', nil, true)]
432
+ strategies = [dummy_strategy_factory('goodbye', nil, true)]
421
433
  allow(subject).to receive(:handle_strategies) { strategies }
422
434
 
423
- expect { subject.ensure_app }.to raise_error(/not find app hello/)
435
+ expect { subject.ensure_app }.to raise_error(/not find app goodbye/)
424
436
  end
425
437
 
426
438
  it 'explains the strategy when it fails' do
427
- apps.pop
428
-
429
- strategies = [dummy_strategy_factory('hello', nil, true)]
439
+ strategies = [dummy_strategy_factory('goodbye', nil, true)]
430
440
  allow(subject).to receive(:handle_strategies) { strategies }
431
441
 
432
442
  expect { subject.ensure_app }.to raise_error(/from dummy/)
433
443
  end
434
444
 
435
445
  it 'indicates the environment when the app search was scoped' do
436
- apps.pop
437
-
438
- strategies = [dummy_strategy_factory('hello', 'aptible', true)]
446
+ strategies = [dummy_strategy_factory('goodbye', 'aptible', true)]
439
447
  allow(subject).to receive(:handle_strategies) { strategies }
440
448
 
441
449
  expect(subject).to receive(:environment_from_handle).with('aptible')
@@ -445,7 +453,12 @@ describe Aptible::CLI::Agent do
445
453
  end
446
454
 
447
455
  it 'fails if multiple apps are found' do
448
- apps << Fabricate(:app, handle: 'hello')
456
+ error = HyperResource::ClientError.new('multiple resources found')
457
+ allow(error).to receive(:body)
458
+ .and_return('error' => 'multiple_resources_found')
459
+ allow(Aptible::Api::App).to receive(:find_by_url)
460
+ .with('/find/app?handle=hello', token: token)
461
+ .and_raise(error)
449
462
 
450
463
  strategies = [dummy_strategy_factory('hello', nil, true)]
451
464
  allow(subject).to receive(:handle_strategies) { strategies }
@@ -13,7 +13,9 @@ describe Aptible::CLI::Agent do
13
13
 
14
14
  before do
15
15
  allow(subject).to receive(:fetch_token).and_return(token)
16
- allow(Aptible::Api::Account).to receive(:all) { [account] }
16
+ allow(Aptible::Api::Account).to receive(:find_by_url)
17
+ .with("/find/account?handle=#{account.handle}", token: token)
18
+ .and_return(account)
17
19
  end
18
20
 
19
21
  describe '#backup_retention_policy' do
@@ -20,7 +20,24 @@ describe Aptible::CLI::Agent do
20
20
 
21
21
  before do
22
22
  allow(subject).to receive(:fetch_token).and_return(token)
23
- allow(Aptible::Api::Account).to receive(:all) { [account, alt_account] }
23
+ allow(Aptible::Api::Account).to receive(:find_by_url)
24
+ .with("/find/account?handle=#{account.handle}", token: token)
25
+ .and_return(account)
26
+ allow(Aptible::Api::Account).to receive(:find_by_url)
27
+ .with("/find/account?handle=#{alt_account.handle}", token: token)
28
+ .and_return(alt_account)
29
+ allow(Aptible::Api::Database).to receive(:find_by_url)
30
+ .with("/find/database?handle=#{default_handle}", token: token)
31
+ .and_return(database)
32
+ allow(Aptible::Api::Database).to receive(:find_by_url)
33
+ .with("/find/database?handle=#{default_handle}&environment=#{account.handle}", token: token)
34
+ .and_return(database)
35
+ allow(Aptible::Api::Database).to receive(:find_by_url)
36
+ .with("/find/database?handle=#{database.handle}", token: token)
37
+ .and_return(database)
38
+ allow(Aptible::Api::Database).to receive(:find_by_url)
39
+ .with("/find/database?handle=#{database.handle}&environment=#{account.handle}", token: token)
40
+ .and_return(database)
24
41
  end
25
42
 
26
43
  describe '#backup:restore' do
@@ -60,6 +77,11 @@ describe Aptible::CLI::Agent do
60
77
 
61
78
  it 'accepts a handle' do
62
79
  h = 'some-handle'
80
+ restored = Fabricate(:database, account: account, handle: h)
81
+
82
+ allow(Aptible::Api::Database).to receive(:find_by_url)
83
+ .with("/find/database?handle=#{h}&environment=#{account.handle}", token: token)
84
+ .and_return(database)
63
85
 
64
86
  expect(backup).to receive(:create_operation!) do |options|
65
87
  expect(options[:handle]).to eq(h)
@@ -70,7 +92,7 @@ describe Aptible::CLI::Agent do
70
92
  end
71
93
 
72
94
  expect(subject).to receive(:attach_to_operation_logs).with(op) do
73
- Fabricate(:database, account: account, handle: h)
95
+ restored
74
96
  end
75
97
 
76
98
  subject.options = { handle: h }
@@ -143,6 +165,9 @@ describe Aptible::CLI::Agent do
143
165
  end
144
166
 
145
167
  subject.options = { environment: 'alt' }
168
+ allow(Aptible::Api::Database).to receive(:find_by_url)
169
+ .with("/find/database?handle=#{default_handle}&environment=alt", token: token)
170
+ .and_return(database)
146
171
  subject.send('backup:restore', 1)
147
172
  end
148
173
  end
@@ -150,7 +175,6 @@ describe Aptible::CLI::Agent do
150
175
 
151
176
  describe '#backup:list' do
152
177
  before { allow(Aptible::Api::Account).to receive(:all) { [account] } }
153
- before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
154
178
 
155
179
  before do
156
180
  m = allow(database).to receive(:each_backup)
@@ -192,6 +216,7 @@ describe Aptible::CLI::Agent do
192
216
  end
193
217
 
194
218
  it 'fails if the DB is not found' do
219
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
195
220
  expect { subject.send('backup:list', 'nope') }
196
221
  .to raise_error(Thor::Error, 'Could not find database nope')
197
222
  end
@@ -8,9 +8,9 @@ describe Aptible::CLI::Agent do
8
8
  before { allow(subject).to receive(:fetch_token).and_return(token) }
9
9
 
10
10
  before do
11
- allow(Aptible::Api::App).to receive(:all)
12
- .with(token: token, href: '/apps?per_page=5000&no_embed=true')
13
- .and_return([app])
11
+ allow(Aptible::Api::App).to receive(:find_by_url)
12
+ .with("/find/app?handle=#{app.handle}", token: token)
13
+ .and_return(app)
14
14
  allow(Aptible::Api::Account).to receive(:all)
15
15
  .with(token: token, href: '/apps?per_page=5000&no_embed=true')
16
16
  .and_return([account])
@@ -13,11 +13,17 @@ describe Aptible::CLI::Agent do
13
13
  allow(Aptible::Api::DatabaseCredential).to receive(:all) do
14
14
  database.database_credentials
15
15
  end
16
+ allow(Aptible::Api::Database).to receive(:find_by_url)
17
+ .with("/find/database?handle=#{handle}", token: token)
18
+ .and_return(database)
19
+ allow(Aptible::Api::Database).to receive(:find_by_url)
20
+ .with("/find/database?handle=#{handle}&environment=#{account.handle}", token: token)
21
+ .and_return(database)
16
22
  end
17
23
 
18
24
  let(:handle) { 'foobar' }
19
25
  let(:stack) { Fabricate(:stack, internal_domain: 'aptible.in') }
20
- let(:account) { Fabricate(:account, stack: stack) }
26
+ let(:account) { Fabricate(:account, stack: stack, handle: 'aptible') }
21
27
  let(:database) { Fabricate(:database, handle: handle, account: account) }
22
28
  let(:socat_helper) { SocatHelperMock.new(port: 4242) }
23
29
 
@@ -151,15 +157,15 @@ describe Aptible::CLI::Agent do
151
157
 
152
158
  describe '#db:tunnel' do
153
159
  it 'should fail if database is non-existent' do
154
- allow(Aptible::Api::Database).to receive(:all) { [] }
160
+ allow(Aptible::Api::Database).to receive(:find_by_url)
161
+ .with("/find/database?handle=#{handle}", token: token)
162
+ .and_return(nil)
155
163
  expect do
156
164
  subject.send('db:tunnel', handle)
157
165
  end.to raise_error("Could not find database #{handle}")
158
166
  end
159
167
 
160
168
  context 'valid database' do
161
- before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
162
-
163
169
  it 'prints a message explaining how to connect' do
164
170
  cred = Fabricate(:database_credential, default: true, type: 'foo',
165
171
  database: database)
@@ -371,6 +377,9 @@ describe Aptible::CLI::Agent do
371
377
  allow(Aptible::Api::Account).to receive(:all)
372
378
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
373
379
  .and_return([staging, prod])
380
+ allow(Aptible::Api::Account).to receive(:find_by_url)
381
+ .with("/find/account?handle=#{staging.handle}", token: token)
382
+ .and_return(staging)
374
383
  allow(Aptible::Api::ExternalAwsResource).to receive(:all)
375
384
  .with(token: token)
376
385
  .and_return([])
@@ -406,6 +415,7 @@ describe Aptible::CLI::Agent do
406
415
  end
407
416
 
408
417
  context 'when an invalid account is specified' do
418
+ before { allow(Aptible::Api::Account).to receive(:find_by_url).and_return(nil) }
409
419
  it 'prints out an error' do
410
420
  subject.options = { environment: 'foo' }
411
421
  expect { subject.send('db:list') }
@@ -544,6 +554,9 @@ describe Aptible::CLI::Agent do
544
554
  allow(Aptible::Api::Account).to receive(:all)
545
555
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
546
556
  .and_return([staging, prod])
557
+ allow(Aptible::Api::Account).to receive(:find_by_url)
558
+ .with("/find/account?handle=#{staging.handle}", token: token)
559
+ .and_return(staging)
547
560
  allow(Aptible::Api::ExternalAwsResource).to receive(:all)
548
561
  .with(token: token)
549
562
  .and_return([staging_rds, prod_rds, unattached_rds])
@@ -627,7 +640,6 @@ describe Aptible::CLI::Agent do
627
640
 
628
641
  describe '#db:backup' do
629
642
  before { allow(Aptible::Api::Account).to receive(:all) { [account] } }
630
- before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
631
643
 
632
644
  let(:op) { Fabricate(:operation) }
633
645
 
@@ -642,6 +654,7 @@ describe Aptible::CLI::Agent do
642
654
  end
643
655
 
644
656
  it 'fails if the DB is not found' do
657
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
645
658
  expect { subject.send('db:backup', 'nope') }
646
659
  .to raise_error(Thor::Error, 'Could not find database nope')
647
660
  end
@@ -649,7 +662,6 @@ describe Aptible::CLI::Agent do
649
662
 
650
663
  describe '#db:reload' do
651
664
  before { allow(Aptible::Api::Account).to receive(:all) { [account] } }
652
- before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
653
665
 
654
666
  let(:op) { Fabricate(:operation) }
655
667
 
@@ -664,6 +676,7 @@ describe Aptible::CLI::Agent do
664
676
  end
665
677
 
666
678
  it 'fails if the DB is not found' do
679
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
667
680
  expect { subject.send('db:reload', 'nope') }
668
681
  .to raise_error(Thor::Error, 'Could not find database nope')
669
682
  end
@@ -671,7 +684,6 @@ describe Aptible::CLI::Agent do
671
684
 
672
685
  describe '#db:restart' do
673
686
  before { allow(Aptible::Api::Account).to receive(:all) { [account] } }
674
- before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
675
687
 
676
688
  let(:op) { Fabricate(:operation) }
677
689
 
@@ -736,6 +748,7 @@ describe Aptible::CLI::Agent do
736
748
  end
737
749
 
738
750
  it 'fails if the DB is not found' do
751
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
739
752
  expect { subject.send('db:restart', 'nope') }
740
753
  .to raise_error(Thor::Error, 'Could not find database nope')
741
754
  end
@@ -743,7 +756,6 @@ describe Aptible::CLI::Agent do
743
756
 
744
757
  describe '#db:modify' do
745
758
  before { allow(Aptible::Api::Account).to receive(:all) { [account] } }
746
- before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
747
759
 
748
760
  let(:op) { Fabricate(:operation) }
749
761
 
@@ -783,16 +795,15 @@ describe Aptible::CLI::Agent do
783
795
  end
784
796
 
785
797
  it 'fails if the DB is not found' do
798
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
786
799
  expect { subject.send('db:modify', 'nope') }
787
800
  .to raise_error(Thor::Error, 'Could not find database nope')
788
801
  end
789
802
  end
790
803
 
791
804
  describe '#db:url' do
792
- let(:databases) { [database] }
793
- before { expect(Aptible::Api::Database).to receive(:all) { databases } }
794
-
795
805
  it 'fails if the DB is not found' do
806
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
796
807
  expect { subject.send('db:url', 'nope') }
797
808
  .to raise_error(Thor::Error, 'Could not find database nope')
798
809
  end
@@ -808,7 +819,12 @@ describe Aptible::CLI::Agent do
808
819
  end
809
820
 
810
821
  it 'fails if multiple DBs are found' do
811
- databases << database
822
+ error = HyperResource::ClientError.new('multiple resources found')
823
+ allow(error).to receive(:body)
824
+ .and_return('error' => 'multiple_resources_found')
825
+ allow(Aptible::Api::Database).to receive(:find_by_url)
826
+ .with("/find/database?handle=#{handle}", token: token)
827
+ .and_raise(error)
812
828
 
813
829
  expect { subject.send('db:url', handle) }
814
830
  .to raise_error(/Multiple databases/)
@@ -817,16 +833,18 @@ describe Aptible::CLI::Agent do
817
833
  end
818
834
 
819
835
  describe '#db:replicate' do
820
- let(:databases) { [] }
821
- before { allow(Aptible::Api::Database).to receive(:all) { databases } }
836
+ let(:master) { Fabricate(:database, handle: 'master') }
837
+ let(:replica) { Fabricate(:database, account: master.account, handle: 'replica') }
838
+ before do
839
+ allow(Aptible::Api::Database).to receive(:find_by_url)
840
+ .with("/find/database?handle=#{master.handle}", token: token)
841
+ .and_return(master)
842
+ allow(Aptible::Api::Database).to receive(:find_by_url)
843
+ .with("/find/database?handle=#{replica.handle}&environment=#{account.handle}", token: token)
844
+ .and_return(replica)
845
+ end
822
846
 
823
847
  def expect_replicate_database(opts = {})
824
- master = Fabricate(:database, handle: 'master')
825
- databases << master
826
- replica = Fabricate(:database,
827
- account: master.account,
828
- handle: 'replica')
829
-
830
848
  op = Fabricate(:operation)
831
849
 
832
850
  params = { type: 'replicate', handle: 'replica' }.merge(opts)
@@ -835,7 +853,6 @@ describe Aptible::CLI::Agent do
835
853
  .with(**params).and_return(op)
836
854
 
837
855
  expect(subject).to receive(:attach_to_operation_logs).with(op) do
838
- databases << replica
839
856
  replica
840
857
  end
841
858
 
@@ -867,17 +884,12 @@ describe Aptible::CLI::Agent do
867
884
  end
868
885
 
869
886
  it 'fails if the DB is not found' do
887
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
870
888
  expect { subject.send('db:replicate', 'nope', 'replica') }
871
889
  .to raise_error(Thor::Error, 'Could not find database nope')
872
890
  end
873
891
 
874
892
  it 'allows logical replication of a database with --version set' do
875
- master = Fabricate(:database, handle: 'master')
876
- databases << master
877
- replica = Fabricate(:database,
878
- account: master.account,
879
- handle: 'replica')
880
-
881
893
  dbimg = Fabricate(:database_image,
882
894
  type: 'postgresql',
883
895
  version: 10,
@@ -894,7 +906,6 @@ describe Aptible::CLI::Agent do
894
906
  .with(**params).and_return(op)
895
907
 
896
908
  expect(subject).to receive(:attach_to_operation_logs).with(op) do
897
- databases << replica
898
909
  replica
899
910
  end
900
911
 
@@ -914,9 +925,6 @@ describe Aptible::CLI::Agent do
914
925
  end
915
926
 
916
927
  it 'fails if logical replication requested without --version' do
917
- master = Fabricate(:database, handle: 'master', type: 'postgresql')
918
- databases << master
919
-
920
928
  subject.options = { type: 'replicate', handle: 'replica', logical: true }
921
929
  expect { subject.send('db:replicate', 'master', 'replica') }
922
930
  .to raise_error(Thor::Error, '--version is required for logical ' \
@@ -924,9 +932,7 @@ describe Aptible::CLI::Agent do
924
932
  end
925
933
 
926
934
  it 'fails if logical replication requested for non-postgres db' do
927
- master = Fabricate(:database, handle: 'master', type: 'mysql')
928
- databases << master
929
-
935
+ master.type = 'mysql'
930
936
  subject.options = { type: 'replicate', handle: 'replica',
931
937
  logical: true, version: 10 }
932
938
  expect { subject.send('db:replicate', 'master', 'replica') }
@@ -937,17 +943,13 @@ describe Aptible::CLI::Agent do
937
943
 
938
944
  describe '#db:dump' do
939
945
  it 'should fail if database is non-existent' do
940
- allow(Aptible::Api::Database).to receive(:all) { [] }
946
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
941
947
  expect do
942
948
  subject.send('db:dump', handle)
943
949
  end.to raise_error("Could not find database #{handle}")
944
950
  end
945
951
 
946
952
  context 'valid database' do
947
- before do
948
- allow(Aptible::Api::Database).to receive(:all) { [database] }
949
- end
950
-
951
953
  it 'exits with the same code as pg_dump' do
952
954
  exit_status = 123
953
955
  cred = Fabricate(:database_credential, default: true, type: 'foo',
@@ -1132,7 +1134,7 @@ describe Aptible::CLI::Agent do
1132
1134
  describe '#db:execute' do
1133
1135
  sql_path = 'file.sql'
1134
1136
  it 'should fail if database is non-existent' do
1135
- allow(Aptible::Api::Database).to receive(:all) { [] }
1137
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
1136
1138
  expect do
1137
1139
  subject.send('db:execute', handle, sql_path)
1138
1140
  end.to raise_error("Could not find database #{handle}")
@@ -1140,7 +1142,6 @@ describe Aptible::CLI::Agent do
1140
1142
 
1141
1143
  context 'valid database' do
1142
1144
  before do
1143
- allow(Aptible::Api::Database).to receive(:all) { [database] }
1144
1145
  allow(subject).to receive(:`).with(/psql .*/) { `exit 0` }
1145
1146
  end
1146
1147
 
@@ -1338,8 +1339,6 @@ describe Aptible::CLI::Agent do
1338
1339
  end
1339
1340
 
1340
1341
  describe '#db:deprovision' do
1341
- before { expect(Aptible::Api::Database).to receive(:all) { [database] } }
1342
-
1343
1342
  let(:operation) { Fabricate(:operation, resource: database) }
1344
1343
 
1345
1344
  it 'deprovisions a database' do
@@ -1409,7 +1408,9 @@ describe Aptible::CLI::Agent do
1409
1408
  before do
1410
1409
  allow(subject).to receive(:options)
1411
1410
  .and_return(environment: account.handle)
1412
- allow(Aptible::Api::Account).to receive(:all) { [account] }
1411
+ allow(Aptible::Api::Account).to receive(:find_by_url)
1412
+ .with("/find/account?handle=#{account.handle}", token: token)
1413
+ .and_return(account)
1413
1414
  end
1414
1415
  context 'with environment and db' do
1415
1416
  it 'should rename properly' do
@@ -1422,6 +1423,7 @@ describe Aptible::CLI::Agent do
1422
1423
  )
1423
1424
  end
1424
1425
  it 'should fail if db does not exist' do
1426
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
1425
1427
  expect { subject.send('db:rename', 'foo2', 'foo3') }
1426
1428
  .to raise_error(/Could not find database foo2/)
1427
1429
  end
@@ -4,12 +4,17 @@ describe Aptible::CLI::Agent do
4
4
  let!(:account) { Fabricate(:account, handle: 'foobar') }
5
5
  let!(:app) { Fabricate(:app, handle: 'hello', account: account) }
6
6
  let(:operation) { Fabricate(:operation) }
7
+ let(:token) { double 'token' }
7
8
 
8
9
  describe '#deploy' do
9
10
  before do
10
- allow(Aptible::Api::App).to receive(:all) { [app] }
11
- allow(Aptible::Api::Account).to receive(:all) { [account] }
12
- allow(subject).to receive(:fetch_token) { double'token' }
11
+ allow(Aptible::Api::App).to receive(:find_by_url)
12
+ .with("/find/app?handle=#{app.handle}&environment=#{account.handle}", token: token)
13
+ .and_return(app)
14
+ allow(subject).to receive(:fetch_token) { token }
15
+ allow(Aptible::Api::Account).to receive(:find_by_url)
16
+ .with("/find/account?handle=#{account.handle}", token: token)
17
+ .and_return(account)
13
18
  end
14
19
 
15
20
  context 'with app' do
@@ -12,6 +12,9 @@ describe Aptible::CLI::Agent do
12
12
  .to receive(:all)
13
13
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
14
14
  .and_return([a1, a2])
15
+ allow(Aptible::Api::Account).to receive(:find_by_url)
16
+ .with("/find/account?handle=#{a2.handle}", token: token)
17
+ .and_return(a2)
15
18
  end
16
19
 
17
20
  def expect_create_certificate(account, options)
@@ -67,10 +70,12 @@ describe Aptible::CLI::Agent do
67
70
  end
68
71
 
69
72
  before do
70
- allow(Aptible::Api::Database)
71
- .to receive(:all)
72
- .with(token: token, href: '/databases?per_page=5000&no_embed=true')
73
- .and_return([db, incomplete])
73
+ allow(Aptible::Api::Database).to receive(:find_by_url)
74
+ .with("/find/database?handle=#{incomplete.handle}", token: token)
75
+ .and_return(incomplete)
76
+ allow(Aptible::Api::Database).to receive(:find_by_url)
77
+ .with("/find/database?handle=#{db.handle}", token: token)
78
+ .and_return(db)
74
79
  allow(db).to receive(:class).and_return(Aptible::Api::Database)
75
80
  allow(incomplete).to receive(:class).and_return(Aptible::Api::Database)
76
81
  stub_options
@@ -78,6 +83,7 @@ describe Aptible::CLI::Agent do
78
83
 
79
84
  describe 'endpoints:database:create' do
80
85
  it 'fails if the DB does not exist' do
86
+ allow(Aptible::Api::Database).to receive(:find_by_url).and_return(nil)
81
87
  expect { subject.send('endpoints:database:create', 'some') }
82
88
  .to raise_error(/could not find database some/im)
83
89
  end
@@ -90,6 +96,9 @@ describe Aptible::CLI::Agent do
90
96
 
91
97
  it 'fails if the DB is not in the account' do
92
98
  stub_options(environment: 'bar')
99
+ expect(Aptible::Api::Database).to receive(:find_by_url)
100
+ .with("/find/database?handle=#{db.handle}&environment=bar", token: token)
101
+ .and_return(nil)
93
102
  expect { subject.send('endpoints:database:create', 'mydb') }
94
103
  .to raise_error(/could not find database mydb/im)
95
104
  end
@@ -223,6 +232,13 @@ describe Aptible::CLI::Agent do
223
232
  .to receive(:all)
224
233
  .with(token: token, href: '/apps?per_page=5000&no_embed=true')
225
234
  .and_return([app])
235
+
236
+ allow(Aptible::Api::App).to receive(:find_by_url)
237
+ .and_return(nil)
238
+ allow(Aptible::Api::App).to receive(:find_by_url)
239
+ .with("/find/app?handle=#{app.handle}", token: token)
240
+ .and_return(app)
241
+
226
242
  allow(app).to receive(:class).and_return(Aptible::Api::App)
227
243
  stub_options
228
244
  end
@@ -16,6 +16,9 @@ describe Aptible::CLI::Agent do
16
16
  .to receive(:all)
17
17
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
18
18
  .and_return([a1, a2])
19
+ allow(Aptible::Api::Account).to receive(:find_by_url)
20
+ .with("/find/account?handle=#{a1.handle}", token: token)
21
+ .and_return(a1)
19
22
  end
20
23
 
21
24
  describe('#environment:list') do
@@ -123,6 +126,7 @@ describe Aptible::CLI::Agent do
123
126
  )
124
127
  end
125
128
  it 'should fail if env does not exist' do
129
+ allow(Aptible::Api::Account).to receive(:find_by_url).and_return(nil)
126
130
  expect { subject.send('environment:rename', 'foo1', 'foo2') }
127
131
  .to raise_error(/Could not find environment foo1/)
128
132
  end
@@ -22,6 +22,10 @@ describe Aptible::CLI::Agent do
22
22
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
23
23
  .and_return([account])
24
24
 
25
+ allow(Aptible::Api::Account).to receive(:find_by_url)
26
+ .with("/find/account?handle=#{account.handle}", token: token)
27
+ .and_return(account)
28
+
25
29
  allow(account).to receive(:reload).and_return(account)
26
30
  end
27
31
 
@@ -87,6 +91,11 @@ describe Aptible::CLI::Agent do
87
91
 
88
92
  context 'elasticsearch' do
89
93
  let(:db) { Fabricate(:database, account: account, id: 5) }
94
+ before do
95
+ allow(Aptible::Api::Database).to receive(:find_by_url)
96
+ .with("/find/database?handle=#{db.handle}&environment=#{db.account.handle}", token: token)
97
+ .and_return(db)
98
+ end
90
99
 
91
100
  it 'creates a new Elasticsearch log drain' do
92
101
  opts = {
@@ -4,18 +4,23 @@ describe Aptible::CLI::Agent do
4
4
  before do
5
5
  allow(subject).to receive(:ask)
6
6
  allow(subject).to receive(:save_token)
7
- allow(subject).to receive(:fetch_token) { 'some token' }
7
+ allow(subject).to receive(:fetch_token) { token }
8
8
  end
9
9
 
10
+ let(:token) { 'some token' }
10
11
  let(:app) { Fabricate(:app, handle: 'foo') }
11
12
  let(:database) { Fabricate(:database, handle: 'bar', status: 'provisioned') }
12
13
  let(:service) { Fabricate(:service, app: app) }
13
14
 
14
15
  describe '#logs' do
15
- before { allow(Aptible::Api::Account).to receive(:all) { [app.account] } }
16
+ before do
17
+ allow(Aptible::Api::Account).to receive(:all) { [app.account] }
18
+ allow(Aptible::Api::App).to receive(:find_by_url)
19
+ .with("/find/app?handle=#{app.handle}", token: 'some token')
20
+ .and_return(app)
21
+ end
16
22
 
17
23
  context 'App resource' do
18
- before { allow(Aptible::Api::App).to receive(:all) { [app] } }
19
24
  before { subject.options = { app: app.handle } }
20
25
 
21
26
  it 'should fail if the app is unprovisioned' do
@@ -35,7 +40,14 @@ describe Aptible::CLI::Agent do
35
40
  end
36
41
 
37
42
  context 'Database resource' do
38
- before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
43
+ before do
44
+ allow(Aptible::Api::Database).to receive(:find_by_url)
45
+ .with("/find/database?handle=#{database.handle}&environment=#{database.account.handle}", token: token)
46
+ .and_return(database)
47
+ allow(Aptible::Api::Database).to receive(:find_by_url)
48
+ .with("/find/database?handle=#{database.handle}", token: token)
49
+ .and_return(database)
50
+ end
39
51
  before { subject.options = { database: database.handle } }
40
52
 
41
53
  it 'should fail if the database is unprovisioned' do
@@ -9,6 +9,9 @@ describe Aptible::CLI::Agent do
9
9
  allow(subject).to receive(:ask)
10
10
  allow(subject).to receive(:save_token)
11
11
  allow(subject).to receive(:fetch_token) { token }
12
+ allow(Aptible::Api::Account).to receive(:find_by_url)
13
+ .with("/find/account?handle=#{staging.handle}", token: token)
14
+ .and_return(staging)
12
15
  end
13
16
 
14
17
  let(:handle) { 'foobar' }
@@ -52,7 +55,6 @@ describe Aptible::CLI::Agent do
52
55
 
53
56
  describe '#maintenance:dbs' do
54
57
  before do
55
- token = 'the-token'
56
58
  allow(subject).to receive(:fetch_token) { token }
57
59
  allow(Aptible::Api::Account).to receive(:all)
58
60
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
@@ -112,6 +114,8 @@ describe Aptible::CLI::Agent do
112
114
  end
113
115
 
114
116
  context 'when an invalid account is specified' do
117
+ before { allow(Aptible::Api::Account).to receive(:find_by_url).and_return(nil) }
118
+
115
119
  it 'prints out an error' do
116
120
  subject.options = { environment: 'foo' }
117
121
  expect { subject.send('maintenance:dbs') }
@@ -121,7 +125,6 @@ describe Aptible::CLI::Agent do
121
125
  end
122
126
  describe '#maintenance:apps' do
123
127
  before do
124
- token = 'the-token'
125
128
  allow(subject).to receive(:fetch_token) { token }
126
129
  allow(Aptible::Api::Account).to receive(:all)
127
130
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
@@ -180,6 +183,8 @@ describe Aptible::CLI::Agent do
180
183
  end
181
184
 
182
185
  context 'when an invalid account is specified' do
186
+ before { allow(Aptible::Api::Account).to receive(:find_by_url).and_return(nil) }
187
+
183
188
  it 'prints out an error' do
184
189
  subject.options = { environment: 'foo' }
185
190
  expect { subject.send('maintenance:apps') }
@@ -21,6 +21,10 @@ describe Aptible::CLI::Agent do
21
21
  allow(Aptible::Api::Account).to receive(:all)
22
22
  .with(token: token, href: '/accounts?per_page=5000&no_embed=true')
23
23
  .and_return([account])
24
+
25
+ allow(Aptible::Api::Account).to receive(:find_by_url)
26
+ .with("/find/account?handle=#{account.handle}", token: token)
27
+ .and_return(account)
24
28
  end
25
29
 
26
30
  describe '#metric_drain:list' do
@@ -57,8 +61,6 @@ describe Aptible::CLI::Agent do
57
61
  it 'lists metric drains for a single account with --environment' do
58
62
  other_account = Fabricate(:account)
59
63
  Fabricate(:metric_drain, handle: 'test2', account: other_account)
60
- accounts = [account, other_account]
61
- allow(Aptible::Api::Account).to receive(:all).and_return(accounts)
62
64
 
63
65
  subject.options = { environment: account.handle }
64
66
  subject.send('metric_drain:list')
@@ -86,6 +88,12 @@ describe Aptible::CLI::Agent do
86
88
  context 'influxdb' do
87
89
  let(:db) { Fabricate(:database, account: account, id: 5) }
88
90
 
91
+ before do
92
+ allow(Aptible::Api::Database).to receive(:find_by_url)
93
+ .with("/find/database?handle=#{db.handle}&environment=#{db.account.handle}", token: token)
94
+ .and_return(db)
95
+ end
96
+
89
97
  it 'creates a new InfluxDB metric drain' do
90
98
  opts = {
91
99
  handle: 'test-influxdb',
@@ -6,10 +6,9 @@ describe Aptible::CLI::Agent do
6
6
 
7
7
  before do
8
8
  allow(subject).to receive(:fetch_token) { token }
9
- allow(Aptible::Api::App)
10
- .to receive(:all)
11
- .with(token: token, href: '/apps?per_page=5000&no_embed=true')
12
- .and_return([app])
9
+ allow(Aptible::Api::App).to receive(:find_by_url)
10
+ .with("/find/app?handle=#{app.handle}", token: token)
11
+ .and_return(app)
13
12
  end
14
13
 
15
14
  describe '#services' do
data/spec/spec_helper.rb CHANGED
@@ -81,6 +81,8 @@ module SpecHarness
81
81
  end
82
82
 
83
83
  RSpec.configure do |config|
84
+ config.example_status_persistence_file_path = 'spec/reports/examples.txt'
85
+
84
86
  config.before(:each) do
85
87
  reset_spec_harness
86
88
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aptible-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.4
4
+ version: 0.26.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Macreery