aptible-cli 0.16.0 → 0.16.1
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 +4 -4
- data/README.md +1 -1
- data/lib/aptible/cli/resource_formatter.rb +14 -0
- data/lib/aptible/cli/subcommands/apps.rb +9 -1
- data/lib/aptible/cli/subcommands/db.rb +13 -4
- data/lib/aptible/cli/version.rb +1 -1
- data/spec/aptible/cli/subcommands/apps_spec.rb +46 -1
- data/spec/aptible/cli/subcommands/db_spec.rb +79 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7a82ca8dc7db1d4eb55e92d7a78f8dda19f3b0e868d913695f9a974079cdf45
|
4
|
+
data.tar.gz: b043caa7662d1406a445e53e02daecdeb08e17a2fadeb448f94155091ac8c6d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d70a4ebaf642e840db0ec5bdfc287a5ca692cf4113173251e6480818b29ad70ee83792672f601a41495b8c55312196835a3e7b12b9364290f95191fae1c2f7c
|
7
|
+
data.tar.gz: f3c1b30a29637d5f872349e45d54d8ce0856a2a467039483bb4cfac872204c15cb2d249650acb5debb7274584aa176459750473ca5cc2d6dc01e63435ce6042b
|
data/README.md
CHANGED
@@ -44,7 +44,7 @@ Commands:
|
|
44
44
|
aptible db:clone SOURCE DEST # Clone a database to create a new one
|
45
45
|
aptible db:create HANDLE [--type TYPE] [--version VERSION] [--container-size SIZE_MB] [--size SIZE_GB] # Create a new database
|
46
46
|
aptible db:deprovision HANDLE # Deprovision a database
|
47
|
-
aptible db:dump HANDLE
|
47
|
+
aptible db:dump HANDLE [pg_dump options] # Dump a remote database to file
|
48
48
|
aptible db:execute HANDLE SQL_FILE # Executes sql against a database
|
49
49
|
aptible db:list # List all databases
|
50
50
|
aptible db:reload HANDLE # Reload a database
|
@@ -9,6 +9,14 @@ module Aptible
|
|
9
9
|
node.value('handle', account.handle)
|
10
10
|
end
|
11
11
|
|
12
|
+
def inject_operation(node, operation)
|
13
|
+
node.value('id', operation.id)
|
14
|
+
node.value('status', operation.status)
|
15
|
+
node.value('git_ref', operation.git_ref)
|
16
|
+
node.value('user_email', operation.user_email)
|
17
|
+
node.value('created_at', operation.created_at)
|
18
|
+
end
|
19
|
+
|
12
20
|
def inject_app(node, app, account)
|
13
21
|
node.value('id', app.id)
|
14
22
|
node.value('handle', app.handle)
|
@@ -16,6 +24,12 @@ module Aptible
|
|
16
24
|
node.value('status', app.status)
|
17
25
|
node.value('git_remote', app.git_repo)
|
18
26
|
|
27
|
+
if app.last_deploy_operation
|
28
|
+
node.keyed_object('last_deploy_operation', 'id') do |n|
|
29
|
+
inject_operation(n, app.last_deploy_operation)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
19
33
|
node.list('services') do |services_list|
|
20
34
|
app.each_service do |service|
|
21
35
|
services_list.object do |n|
|
@@ -119,7 +119,15 @@ module Aptible
|
|
119
119
|
define_method 'apps:deprovision' do
|
120
120
|
app = ensure_app(options)
|
121
121
|
CLI.logger.info "Deprovisioning #{app.handle}..."
|
122
|
-
app.create_operation!(type: 'deprovision')
|
122
|
+
op = app.create_operation!(type: 'deprovision')
|
123
|
+
begin
|
124
|
+
attach_to_operation_logs(op)
|
125
|
+
rescue HyperResource::ClientError => e
|
126
|
+
# A 404 here means that the operation completed successfully,
|
127
|
+
# and was removed faster than attach_to_operation_logs
|
128
|
+
# could attach to the logs.
|
129
|
+
raise if e.response.status != 404
|
130
|
+
end
|
123
131
|
end
|
124
132
|
end
|
125
133
|
end
|
@@ -113,14 +113,15 @@ module Aptible
|
|
113
113
|
render_database(database, database.account)
|
114
114
|
end
|
115
115
|
|
116
|
-
desc 'db:dump HANDLE
|
116
|
+
desc 'db:dump HANDLE [pg_dump options]',
|
117
|
+
'Dump a remote database to file'
|
117
118
|
option :environment
|
118
|
-
define_method 'db:dump' do |handle|
|
119
|
+
define_method 'db:dump' do |handle, *dump_options|
|
119
120
|
database = ensure_database(options.merge(db: handle))
|
120
121
|
with_postgres_tunnel(database) do |url|
|
121
122
|
filename = "#{handle}.dump"
|
122
123
|
CLI.logger.info "Dumping to #{filename}"
|
123
|
-
`pg_dump #{url} > #{filename}`
|
124
|
+
`pg_dump #{url} #{dump_options.shelljoin} > #{filename}`
|
124
125
|
end
|
125
126
|
end
|
126
127
|
|
@@ -184,7 +185,15 @@ module Aptible
|
|
184
185
|
define_method 'db:deprovision' do |handle|
|
185
186
|
database = ensure_database(options.merge(db: handle))
|
186
187
|
CLI.logger.info "Deprovisioning #{database.handle}..."
|
187
|
-
database.create_operation!(type: 'deprovision')
|
188
|
+
op = database.create_operation!(type: 'deprovision')
|
189
|
+
begin
|
190
|
+
attach_to_operation_logs(op)
|
191
|
+
rescue HyperResource::ClientError => e
|
192
|
+
# A 404 here means that the operation completed successfully,
|
193
|
+
# and was removed faster than attach_to_operation_logs
|
194
|
+
# could attach to the logs.
|
195
|
+
raise if e.response.status != 404
|
196
|
+
end
|
188
197
|
end
|
189
198
|
|
190
199
|
desc 'db:backup HANDLE', 'Backup a database'
|
data/lib/aptible/cli/version.rb
CHANGED
@@ -133,6 +133,40 @@ describe Aptible::CLI::Agent do
|
|
133
133
|
|
134
134
|
expect(captured_output_json).to eq(expected_json)
|
135
135
|
end
|
136
|
+
|
137
|
+
it 'includes the last deploy operation in JSON' do
|
138
|
+
account = Fabricate(:account, handle: 'account')
|
139
|
+
op = Fabricate(:operation, type: 'deploy', status: 'succeeded')
|
140
|
+
app = Fabricate(:app, account: account, handle: 'app',
|
141
|
+
last_deploy_operation: op)
|
142
|
+
allow(Aptible::Api::Account).to receive(:all).and_return([account])
|
143
|
+
|
144
|
+
expected_json = [
|
145
|
+
{
|
146
|
+
'environment' => {
|
147
|
+
'id' => account.id,
|
148
|
+
'handle' => account.handle
|
149
|
+
},
|
150
|
+
'handle' => app.handle,
|
151
|
+
'id' => app.id,
|
152
|
+
'status' => app.status,
|
153
|
+
'git_remote' => app.git_repo,
|
154
|
+
'last_deploy_operation' =>
|
155
|
+
{
|
156
|
+
'id' => op.id,
|
157
|
+
'status' => op.status,
|
158
|
+
'git_ref' => op.git_ref,
|
159
|
+
'user_email' => op.user_email,
|
160
|
+
'created_at' => op.created_at
|
161
|
+
},
|
162
|
+
'services' => []
|
163
|
+
}
|
164
|
+
]
|
165
|
+
|
166
|
+
subject.send('apps')
|
167
|
+
|
168
|
+
expect(captured_output_json).to eq(expected_json)
|
169
|
+
end
|
136
170
|
end
|
137
171
|
|
138
172
|
describe '#apps:create' do
|
@@ -305,7 +339,18 @@ describe Aptible::CLI::Agent do
|
|
305
339
|
expect(app).to receive(:create_operation!)
|
306
340
|
.with(type: 'deprovision').and_return(operation)
|
307
341
|
|
308
|
-
expect(subject).
|
342
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
343
|
+
|
344
|
+
subject.send('apps:deprovision')
|
345
|
+
end
|
346
|
+
it 'does not fail if the operation cannot be found' do
|
347
|
+
expect(app).to receive(:create_operation!)
|
348
|
+
.with(type: 'deprovision').and_return(operation)
|
349
|
+
|
350
|
+
response = Faraday::Response.new(status: 404)
|
351
|
+
error = HyperResource::ClientError.new('Not Found', response: response)
|
352
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
353
|
+
.and_raise(error)
|
309
354
|
|
310
355
|
subject.send('apps:deprovision')
|
311
356
|
end
|
@@ -439,6 +439,73 @@ describe Aptible::CLI::Agent do
|
|
439
439
|
end
|
440
440
|
end
|
441
441
|
|
442
|
+
describe '#db:dump' do
|
443
|
+
it 'should fail if database is non-existent' do
|
444
|
+
allow(Aptible::Api::Database).to receive(:all) { [] }
|
445
|
+
expect do
|
446
|
+
subject.send('db:dump', handle)
|
447
|
+
end.to raise_error("Could not find database #{handle}")
|
448
|
+
end
|
449
|
+
|
450
|
+
context 'valid database' do
|
451
|
+
before do
|
452
|
+
allow(Aptible::Api::Database).to receive(:all) { [database] }
|
453
|
+
allow(subject).to receive(:`).with(/pg_dump .*/)
|
454
|
+
end
|
455
|
+
|
456
|
+
it 'prints a message indicating the dump is happening' do
|
457
|
+
cred = Fabricate(:database_credential, default: true, type: 'foo',
|
458
|
+
database: database)
|
459
|
+
|
460
|
+
expect(subject).to receive(:with_local_tunnel).with(cred)
|
461
|
+
.and_yield(socat_helper)
|
462
|
+
|
463
|
+
subject.send('db:dump', handle)
|
464
|
+
|
465
|
+
expect(captured_logs)
|
466
|
+
.to match(/Dumping to foobar.dump/i)
|
467
|
+
end
|
468
|
+
|
469
|
+
it 'invokes pg_dump with the tunnel url' do
|
470
|
+
cred = Fabricate(:database_credential, default: true, type: 'foo',
|
471
|
+
database: database)
|
472
|
+
|
473
|
+
expect(subject).to receive(:with_local_tunnel).with(cred)
|
474
|
+
.and_yield(socat_helper)
|
475
|
+
|
476
|
+
local_url = 'postgresql://aptible:password@localhost.aptible.in:4242/db'
|
477
|
+
|
478
|
+
expect(subject).to receive(:`)
|
479
|
+
.with(/pg_dump #{local_url} > foobar.dump/)
|
480
|
+
|
481
|
+
subject.send('db:dump', handle)
|
482
|
+
end
|
483
|
+
|
484
|
+
it 'sends extra options if given' do
|
485
|
+
cred = Fabricate(:database_credential, default: true, type: 'foo',
|
486
|
+
database: database)
|
487
|
+
|
488
|
+
expect(subject).to receive(:with_local_tunnel).with(cred)
|
489
|
+
.and_yield(socat_helper)
|
490
|
+
|
491
|
+
pg_dump_options = '--exclude-table-data=events ' \
|
492
|
+
'--exclude-table-data=versions'
|
493
|
+
allow(subject).to receive(:`).with(/pg_dump .* #{pg_dump_options} .*/)
|
494
|
+
|
495
|
+
subject.send('db:dump', handle,
|
496
|
+
'--exclude-table-data=events',
|
497
|
+
'--exclude-table-data=versions')
|
498
|
+
end
|
499
|
+
|
500
|
+
it 'fails when the database is not provisioned' do
|
501
|
+
allow(database).to receive(:status) { 'pending' }
|
502
|
+
|
503
|
+
expect { subject.send('db:dump', handle) }
|
504
|
+
.to raise_error(/foobar is not provisioned/im)
|
505
|
+
end
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
442
509
|
describe '#db:deprovision' do
|
443
510
|
before { expect(Aptible::Api::Database).to receive(:all) { [database] } }
|
444
511
|
|
@@ -448,7 +515,18 @@ describe Aptible::CLI::Agent do
|
|
448
515
|
expect(database).to receive(:create_operation!)
|
449
516
|
.with(type: 'deprovision').and_return(operation)
|
450
517
|
|
451
|
-
expect(subject).
|
518
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
519
|
+
|
520
|
+
subject.send('db:deprovision', handle)
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'does not fail if the operation cannot be found' do
|
524
|
+
expect(database).to receive(:create_operation!)
|
525
|
+
.with(type: 'deprovision').and_return(operation)
|
526
|
+
response = Faraday::Response.new(status: 404)
|
527
|
+
error = HyperResource::ClientError.new('Not Found', response: response)
|
528
|
+
expect(subject).to receive(:attach_to_operation_logs).with(operation)
|
529
|
+
.and_raise(error)
|
452
530
|
|
453
531
|
subject.send('db:deprovision', handle)
|
454
532
|
end
|
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.16.
|
4
|
+
version: 0.16.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Macreery
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aptible-resource
|