aptible-cli 0.16.8 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f9abbc0bef99a8ca0f69c0b3d9751e529d9b37b5528315b03481acc84b68868
4
- data.tar.gz: 916d97a558b654865ae9cbcf4532058a9070d19dbe6d984be7a5f233eb2884e6
3
+ metadata.gz: 9ffdd3315dbbee4f94b8b02bb6c6695829c511cf950448997b603cce77253d20
4
+ data.tar.gz: ac9983ee76d69580194e58d1f1acd6927f4addcbe2dbaec132ae133aa13d215a
5
5
  SHA512:
6
- metadata.gz: 6ef0c0c9dc25afdf19b680fcabcfd589cd74f246d7442361e79ef5f01d73382bd10ee21c9ca63a31a3f6a003ef0405c651b03e251c6e36525ddfebc86df7aeee
7
- data.tar.gz: 3457904ef7ab8e5ff0a5a63fd856633fea48460e8dd88b0ae5ba8181494d893bfe45027927e57c7b217cc89fb39f09eb3fe27abdcb929d1b6fd8d6ca7a6a5b18
6
+ metadata.gz: d4721d191f0f6c35f6f75717b1896a5ca44441e3d912cb9af23bcde319f9f7678881a7eaf14de89e3222834c139d8c8c7bbe3eb9239d980ec55d32b47acbd835
7
+ data.tar.gz: 2ced7b764b4b1b0db0ed460a0afd3f14836054a15ec32d5681af077a6811743fddff655c3d27121abc6858729116d385eff2da2d0c807cbbcef3abf92b2b0183
data/.gitignore CHANGED
@@ -17,4 +17,4 @@ test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
19
  /.idea
20
-
20
+ /.vscode
data/README.md CHANGED
@@ -48,9 +48,10 @@ Commands:
48
48
  aptible db:dump HANDLE [pg_dump options] # Dump a remote database to file
49
49
  aptible db:execute HANDLE SQL_FILE [--on-error-stop] # Executes sql against a database
50
50
  aptible db:list # List all databases
51
+ aptible db:modify HANDLE [--iops IOPS] [--volume-type [gp2, gp3]] # Modify a database disk
51
52
  aptible db:reload HANDLE # Reload a database
52
53
  aptible db:replicate HANDLE REPLICA_HANDLE [--container-size SIZE_MB] [--disk-size SIZE_GB] [--logical --version VERSION] [--key-arn KEY_ARN] # Create a replica/follower of a database
53
- aptible db:restart HANDLE [--container-size SIZE_MB] [--disk-size SIZE_GB] # Restart a database
54
+ aptible db:restart HANDLE [--container-size SIZE_MB] [--disk-size SIZE_GB][--iops IOPS] [--volume-type [gp2, gp3]] # Restart a database
54
55
  aptible db:tunnel HANDLE # Create a local tunnel to a database
55
56
  aptible db:url HANDLE # Display a database URL
56
57
  aptible db:versions # List available database versions
@@ -66,11 +67,12 @@ Commands:
66
67
  aptible endpoints:tcp:modify [--app APP] ENDPOINT_HOSTNAME # Modify an App TCP Endpoint
67
68
  aptible endpoints:tls:create [--app APP] SERVICE # Create an App TLS Endpoint
68
69
  aptible endpoints:tls:modify [--app APP] ENDPOINT_HOSTNAME # Modify an App TLS Endpoint
70
+ aptible environment:ca_cert # Retrieve the CA certificate associated with the environment
71
+ aptible environment:list # List all environments
69
72
  aptible help [COMMAND] # Describe available commands or one specific command
70
73
  aptible login # Log in to Aptible
71
74
  aptible logs [--app APP | --database DATABASE] # Follows logs from a running app or database
72
75
  aptible operation:cancel OPERATION_ID # Cancel a running operation
73
- aptible ps # Display running processes for an app - DEPRECATED
74
76
  aptible rebuild # Rebuild an app, and restart its services
75
77
  aptible restart # Restart all services associated with an app
76
78
  aptible services # List Services for an App
data/aptible-cli.gemspec CHANGED
@@ -28,7 +28,11 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency 'git'
29
29
  spec.add_dependency 'term-ansicolor'
30
30
  spec.add_dependency 'chronic_duration', '~> 0.10.6'
31
+
32
+ # Temporarily pin ffi until https://github.com/ffi/ffi/issues/868 is fixed
33
+ spec.add_dependency 'ffi', '<= 1.14.1' if Gem.win_platform?
31
34
  spec.add_dependency 'win32-process' if Gem.win_platform?
35
+
32
36
  spec.add_dependency 'activesupport', '>= 4.0', '< 6.0'
33
37
  spec.add_development_dependency 'bundler', '~> 1.3'
34
38
  spec.add_development_dependency 'aptible-tasks', '~> 0.5.8'
data/bin/aptible CHANGED
@@ -10,7 +10,7 @@ end
10
10
  begin
11
11
  Aptible::CLI::Agent.start
12
12
  rescue HyperResource::ClientError => e
13
- m = if e.body['error'] == 'invalid_token'
13
+ m = if %w(invalid_token expired_token).include? e.body['error']
14
14
  'API authentication error: please run aptible login'
15
15
  else
16
16
  "An error occurred: #{e.body['message']}"
@@ -23,8 +23,8 @@ require_relative 'subcommands/apps'
23
23
  require_relative 'subcommands/config'
24
24
  require_relative 'subcommands/db'
25
25
  require_relative 'subcommands/domains'
26
+ require_relative 'subcommands/environment'
26
27
  require_relative 'subcommands/logs'
27
- require_relative 'subcommands/ps'
28
28
  require_relative 'subcommands/rebuild'
29
29
  require_relative 'subcommands/deploy'
30
30
  require_relative 'subcommands/restart'
@@ -47,8 +47,8 @@ module Aptible
47
47
  include Subcommands::Config
48
48
  include Subcommands::DB
49
49
  include Subcommands::Domains
50
+ include Subcommands::Environment
50
51
  include Subcommands::Logs
51
- include Subcommands::Ps
52
52
  include Subcommands::Rebuild
53
53
  include Subcommands::Deploy
54
54
  include Subcommands::Restart
@@ -235,11 +235,7 @@ module Aptible
235
235
 
236
236
  def warn_sso_enforcement
237
237
  # If the user is also a member of
238
- begin
239
- token = fetch_token
240
- rescue StandardError
241
- return
242
- end
238
+ token = fetch_token
243
239
  reauth = Aptible::Auth::ReauthenticateOrganization.all(token: token)
244
240
  return if reauth.empty?
245
241
 
@@ -247,6 +243,7 @@ module Aptible
247
243
  'login method (SSO or Aptible credentials) to access',
248
244
  'these organizations:',
249
245
  reauth.map(&:name)].join(' '))
246
+ rescue StandardError
250
247
  end
251
248
 
252
249
  def version_string
@@ -23,6 +23,7 @@ module Aptible
23
23
  node.value('created_at', backup.created_at)
24
24
  node.value('region', backup.aws_region)
25
25
  node.value('size', backup.size)
26
+ node.value('manual', backup.manual)
26
27
 
27
28
  if backup.copied_from
28
29
  node.keyed_object('copied_from', 'description') do |n|
@@ -81,6 +82,7 @@ module Aptible
81
82
  node.value('handle', database.handle)
82
83
 
83
84
  node.value('type', database.type)
85
+ node.value('version', database.database_image.version)
84
86
  node.value('status', database.status)
85
87
 
86
88
  node.value('connection_url', database.connection_url)
@@ -91,6 +93,20 @@ module Aptible
91
93
  end
92
94
  end
93
95
  attach_account(node, account)
96
+
97
+ if database.disk
98
+ node.value('disk_type', database.disk.ebs_volume_type)
99
+ node.value('disk_size', database.disk.size)
100
+ node.value('disk_modification_progress',
101
+ database.disk.modification_progress)
102
+ node.value('disk_modification_status', database.disk.status)
103
+ node.value('disk_provisioned_iops', database.disk.provisioned_iops)
104
+ end
105
+
106
+ if database.service
107
+ node.value('container_size', \
108
+ database.service.container_memory_limit_mb)
109
+ end
94
110
  end
95
111
 
96
112
  def inject_credential(node, credential)
@@ -279,19 +279,24 @@ module Aptible
279
279
  end
280
280
 
281
281
  desc 'db:restart HANDLE ' \
282
- '[--container-size SIZE_MB] [--disk-size SIZE_GB]',
282
+ '[--container-size SIZE_MB] [--disk-size SIZE_GB]' \
283
+ '[--iops IOPS] [--volume-type [gp2, gp3]]',
283
284
  'Restart a database'
284
285
  option :environment
285
286
  option :container_size, type: :numeric
286
287
  option :disk_size, type: :numeric
287
288
  option :size, type: :numeric
289
+ option :iops, type: :numeric
290
+ option :volume_type
288
291
  define_method 'db:restart' do |handle|
289
292
  database = ensure_database(options.merge(db: handle))
290
293
 
291
294
  opts = {
292
295
  type: 'restart',
293
296
  container_size: options[:container_size],
294
- disk_size: options[:disk_size] || options[:size]
297
+ disk_size: options[:disk_size] || options[:size],
298
+ provisioned_iops: options[:iops],
299
+ ebs_volume_type: options[:volume_type]
295
300
  }.delete_if { |_, v| v.nil? }
296
301
 
297
302
  CLI.logger.warn([
@@ -305,6 +310,26 @@ module Aptible
305
310
  attach_to_operation_logs(op)
306
311
  end
307
312
 
313
+ desc 'db:modify HANDLE ' \
314
+ '[--iops IOPS] [--volume-type [gp2, gp3]]',
315
+ 'Modify a database disk'
316
+ option :environment
317
+ option :iops, type: :numeric
318
+ option :volume_type
319
+ define_method 'db:modify' do |handle|
320
+ database = ensure_database(options.merge(db: handle))
321
+
322
+ opts = {
323
+ type: 'modify',
324
+ provisioned_iops: options[:iops],
325
+ ebs_volume_type: options[:volume_type]
326
+ }.delete_if { |_, v| v.nil? }
327
+
328
+ CLI.logger.info "Modifying #{database.handle}..."
329
+ op = database.create_operation!(opts)
330
+ attach_to_operation_logs(op)
331
+ end
332
+
308
333
  desc 'db:url HANDLE', 'Display a database URL'
309
334
  option :environment
310
335
  option :type, type: :string
@@ -0,0 +1,49 @@
1
+ module Aptible
2
+ module CLI
3
+ module Subcommands
4
+ module Environment
5
+ def self.included(thor)
6
+ thor.class_eval do
7
+ include Helpers::Environment
8
+ include Helpers::Token
9
+
10
+ desc 'environment:list', 'List all environments'
11
+ option :environment
12
+ define_method 'environment:list' do
13
+ Formatter.render(Renderer.current) do |root|
14
+ root.keyed_list(
15
+ 'handle'
16
+ ) do |node|
17
+ scoped_environments(options).each do |account|
18
+ node.object do |n|
19
+ ResourceFormatter.inject_account(n, account)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ desc 'environment:ca_cert',
27
+ 'Retrieve the CA certificate associated with the environment'
28
+ option :environment
29
+ define_method 'environment:ca_cert' do
30
+ Formatter.render(Renderer.current) do |root|
31
+ root.grouped_keyed_list(
32
+ 'handle',
33
+ 'ca_body'
34
+ ) do |node|
35
+ scoped_environments(options).each do |account|
36
+ node.object do |n|
37
+ n.value('ca_body', account.ca_body)
38
+ ResourceFormatter.inject_account(n, account)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,5 @@
1
1
  module Aptible
2
2
  module CLI
3
- VERSION = '0.16.8'.freeze
3
+ VERSION = '0.18.0'.freeze
4
4
  end
5
5
  end
@@ -389,6 +389,31 @@ describe Aptible::CLI::Agent do
389
389
  expect(captured_logs).to match(/restarting foobar/i)
390
390
  end
391
391
 
392
+ it 'allows restarting a database with provisioned iops' do
393
+ expect(database).to receive(:create_operation!)
394
+ .with(type: 'restart', provisioned_iops: 3001)
395
+ .and_return(op)
396
+
397
+ expect(subject).to receive(:attach_to_operation_logs).with(op)
398
+
399
+ subject.options = { iops: 3001 }
400
+ subject.send('db:restart', handle)
401
+
402
+ expect(captured_logs).to match(/restarting foobar/i)
403
+ end
404
+
405
+ it 'allows restarting a database with ebs volume type' do
406
+ expect(database).to receive(:create_operation!)
407
+ .with(type: 'restart', ebs_volume_type: 'gp2').and_return(op)
408
+
409
+ expect(subject).to receive(:attach_to_operation_logs).with(op)
410
+
411
+ subject.options = { volume_type: 'gp2' }
412
+ subject.send('db:restart', handle)
413
+
414
+ expect(captured_logs).to match(/restarting foobar/i)
415
+ end
416
+
392
417
  it 'allows restarting a database with (implicitly disk) size' do
393
418
  expect(database).to receive(:create_operation!)
394
419
  .with(type: 'restart', disk_size: 40).and_return(op)
@@ -419,6 +444,53 @@ describe Aptible::CLI::Agent do
419
444
  end
420
445
  end
421
446
 
447
+ describe '#db:modify' do
448
+ before { allow(Aptible::Api::Account).to receive(:all) { [account] } }
449
+ before { allow(Aptible::Api::Database).to receive(:all) { [database] } }
450
+
451
+ let(:op) { Fabricate(:operation) }
452
+
453
+ it 'allows modifying a database' do
454
+ expect(database).to receive(:create_operation!)
455
+ .with(type: 'modify').and_return(op)
456
+
457
+ expect(subject).to receive(:attach_to_operation_logs).with(op)
458
+
459
+ subject.send('db:modify', handle)
460
+
461
+ expect(captured_logs).to match(/modifying foobar/i)
462
+ end
463
+
464
+ it 'allows modifying a database with provisioned iops' do
465
+ expect(database).to receive(:create_operation!)
466
+ .with(type: 'modify', provisioned_iops: 3001).and_return(op)
467
+
468
+ expect(subject).to receive(:attach_to_operation_logs).with(op)
469
+
470
+ subject.options = { iops: 3001 }
471
+ subject.send('db:modify', handle)
472
+
473
+ expect(captured_logs).to match(/modifying foobar/i)
474
+ end
475
+
476
+ it 'allows modifying a database with ebs volume type' do
477
+ expect(database).to receive(:create_operation!)
478
+ .with(type: 'modify', ebs_volume_type: 'gp2').and_return(op)
479
+
480
+ expect(subject).to receive(:attach_to_operation_logs).with(op)
481
+
482
+ subject.options = { volume_type: 'gp2' }
483
+ subject.send('db:modify', handle)
484
+
485
+ expect(captured_logs).to match(/modifying foobar/i)
486
+ end
487
+
488
+ it 'fails if the DB is not found' do
489
+ expect { subject.send('db:modify', 'nope') }
490
+ .to raise_error(Thor::Error, 'Could not find database nope')
491
+ end
492
+ end
493
+
422
494
  describe '#db:url' do
423
495
  let(:databases) { [database] }
424
496
  before { expect(Aptible::Api::Database).to receive(:all) { databases } }
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Aptible::CLI::Agent do
4
+ let!(:a1) do
5
+ Fabricate(:account, handle: 'foo', ca_body: 'account 1 cert')
6
+ end
7
+ let!(:a2) do
8
+ Fabricate(:account, handle: 'bar', ca_body: '--account 2 cert--')
9
+ end
10
+
11
+ let(:token) { double 'token' }
12
+
13
+ before do
14
+ allow(subject).to receive(:fetch_token) { token }
15
+ allow(Aptible::Api::Account).to receive(:all).with(token: token)
16
+ .and_return([a1, a2])
17
+ end
18
+
19
+ it 'lists avaliable environments' do
20
+ subject.send('environment:list')
21
+
22
+ expect(captured_output_text.split("\n")).to include('foo')
23
+ expect(captured_output_text.split("\n")).to include('bar')
24
+ end
25
+
26
+ it 'fetches certs for all avaliable environments' do
27
+ subject.send('environment:ca_cert')
28
+
29
+ expect(captured_output_text.split("\n")).to include('account 1 cert')
30
+ expect(captured_output_text.split("\n")).to include('--account 2 cert--')
31
+
32
+ expected_accounts = [
33
+ {
34
+ 'handle' => 'foo',
35
+ 'ca_body' => 'account 1 cert'
36
+ },
37
+ {
38
+ 'handle' => 'bar',
39
+ 'ca_body' => '--account 2 cert--'
40
+ }
41
+ ]
42
+ expect(captured_output_json.map! { |account| account.except('id') })
43
+ .to eq(expected_accounts)
44
+ end
45
+
46
+ it 'fetches certs for specified environment' do
47
+ subject.options = { environment: 'foo' }
48
+ subject.send('environment:ca_cert')
49
+
50
+ expect(captured_output_text.split("\n")).to include('account 1 cert')
51
+ expect(captured_output_text.split("\n"))
52
+ .to_not include('--account 2 cert--')
53
+ end
54
+ end
@@ -20,6 +20,7 @@ Fabricator(:account, from: :stub_account) do
20
20
  bastion_host 'localhost'
21
21
  dumptruck_port 1234
22
22
  handle 'aptible'
23
+ ca_body '--BEGIN FAKE CERT-- test --END FAKE CERT--'
23
24
  stack
24
25
 
25
26
  apps { [] }
@@ -0,0 +1,7 @@
1
+ class StubDatabaseDisk < OpenStruct
2
+ end
3
+
4
+ Fabricator(:database_disk, from: :stub_database_disk) do
5
+ size 100
6
+ ebs_volume_type { 'gb2' }
7
+ end
@@ -16,6 +16,8 @@ Fabricator(:database, from: :stub_database) do
16
16
  status 'provisioned'
17
17
  connection_url 'postgresql://aptible:password@10.252.1.125:49158/db'
18
18
  account
19
+ database_image
20
+ disk { Fabricate(:database_disk) }
19
21
  service { nil }
20
22
 
21
23
  backups { [] }
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.8
4
+ version: 0.18.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: 2020-10-23 00:00:00.000000000 Z
11
+ date: 2021-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aptible-resource
@@ -296,10 +296,10 @@ files:
296
296
  - lib/aptible/cli/subcommands/deploy.rb
297
297
  - lib/aptible/cli/subcommands/domains.rb
298
298
  - lib/aptible/cli/subcommands/endpoints.rb
299
+ - lib/aptible/cli/subcommands/environment.rb
299
300
  - lib/aptible/cli/subcommands/inspect.rb
300
301
  - lib/aptible/cli/subcommands/logs.rb
301
302
  - lib/aptible/cli/subcommands/operation.rb
302
- - lib/aptible/cli/subcommands/ps.rb
303
303
  - lib/aptible/cli/subcommands/rebuild.rb
304
304
  - lib/aptible/cli/subcommands/restart.rb
305
305
  - lib/aptible/cli/subcommands/services.rb
@@ -325,6 +325,7 @@ files:
325
325
  - spec/aptible/cli/subcommands/deploy_spec.rb
326
326
  - spec/aptible/cli/subcommands/domains_spec.rb
327
327
  - spec/aptible/cli/subcommands/endpoints_spec.rb
328
+ - spec/aptible/cli/subcommands/environment_spec.rb
328
329
  - spec/aptible/cli/subcommands/inspect_spec.rb
329
330
  - spec/aptible/cli/subcommands/logs_spec.rb
330
331
  - spec/aptible/cli/subcommands/operation_spec.rb
@@ -339,6 +340,7 @@ files:
339
340
  - spec/fabricators/certificate_fabricator.rb
340
341
  - spec/fabricators/configuration_fabricator.rb
341
342
  - spec/fabricators/database_credential_fabricator.rb
343
+ - spec/fabricators/database_disk_fabricator.rb
342
344
  - spec/fabricators/database_fabricator.rb
343
345
  - spec/fabricators/database_image_fabricator.rb
344
346
  - spec/fabricators/operation_fabricator.rb
@@ -398,6 +400,7 @@ test_files:
398
400
  - spec/aptible/cli/subcommands/deploy_spec.rb
399
401
  - spec/aptible/cli/subcommands/domains_spec.rb
400
402
  - spec/aptible/cli/subcommands/endpoints_spec.rb
403
+ - spec/aptible/cli/subcommands/environment_spec.rb
401
404
  - spec/aptible/cli/subcommands/inspect_spec.rb
402
405
  - spec/aptible/cli/subcommands/logs_spec.rb
403
406
  - spec/aptible/cli/subcommands/operation_spec.rb
@@ -412,6 +415,7 @@ test_files:
412
415
  - spec/fabricators/certificate_fabricator.rb
413
416
  - spec/fabricators/configuration_fabricator.rb
414
417
  - spec/fabricators/database_credential_fabricator.rb
418
+ - spec/fabricators/database_disk_fabricator.rb
415
419
  - spec/fabricators/database_fabricator.rb
416
420
  - spec/fabricators/database_image_fabricator.rb
417
421
  - spec/fabricators/operation_fabricator.rb
@@ -1,30 +0,0 @@
1
- require 'shellwords'
2
-
3
- module Aptible
4
- module CLI
5
- module Subcommands
6
- module Ps
7
- def self.included(thor)
8
- thor.class_eval do
9
- include Helpers::Operation
10
- include Helpers::App
11
-
12
- desc 'ps', 'Display running processes for an app - DEPRECATED'
13
- app_options
14
- def ps
15
- deprecated('This command is deprecated on Aptible v2 stacks.')
16
-
17
- app = ensure_app(options)
18
-
19
- op = app.create_operation!(type: 'ps', status: 'succeeded')
20
-
21
- ENV['ACCESS_TOKEN'] = fetch_token
22
- opts = ['-o', 'SendEnv=ACCESS_TOKEN']
23
- exit_with_ssh_portal(op, *opts)
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end