tugboat 3.1.0 → 4.0.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/CODE_OF_CONDUCT.md +46 -0
  4. data/lib/tugboat/cli.rb +7 -1
  5. data/lib/tugboat/config.rb +11 -1
  6. data/lib/tugboat/middleware.rb +2 -0
  7. data/lib/tugboat/middleware/ask_for_credentials.rb +2 -1
  8. data/lib/tugboat/middleware/base.rb +31 -13
  9. data/lib/tugboat/middleware/check_snapshot_parameters.rb +16 -0
  10. data/lib/tugboat/middleware/info_droplet.rb +2 -2
  11. data/lib/tugboat/middleware/inject_client.rb +10 -1
  12. data/lib/tugboat/middleware/list_droplets.rb +5 -3
  13. data/lib/tugboat/version.rb +1 -1
  14. data/spec/cli/add_key_spec.rb +7 -9
  15. data/spec/cli/authorize_cli_spec.rb +4 -34
  16. data/spec/cli/config_cli_spec.rb +10 -5
  17. data/spec/cli/create_cli_spec.rb +20 -17
  18. data/spec/cli/debug_cli_spec.rb +11 -12
  19. data/spec/cli/destroy_cli_spec.rb +35 -12
  20. data/spec/cli/destroy_image_cli_spec.rb +12 -10
  21. data/spec/cli/droplets_cli_spec.rb +74 -48
  22. data/spec/cli/env_variable_spec.rb +4 -4
  23. data/spec/cli/halt_cli_spec.rb +16 -13
  24. data/spec/cli/help_cli_spec.rb +4 -4
  25. data/spec/cli/images_cli_spec.rb +9 -7
  26. data/spec/cli/info_cli_spec.rb +120 -50
  27. data/spec/cli/info_image_cli_spec.rb +24 -23
  28. data/spec/cli/keys_cli_spec.rb +3 -3
  29. data/spec/cli/password_reset_cli_spec.rb +12 -12
  30. data/spec/cli/rebuild_cli_spec.rb +31 -24
  31. data/spec/cli/regions_cli_spec.rb +3 -3
  32. data/spec/cli/resize_cli_spec.rb +16 -16
  33. data/spec/cli/restart_cli_spec.rb +32 -11
  34. data/spec/cli/sizes_cli_spec.rb +3 -3
  35. data/spec/cli/snapshot_cli_spec.rb +25 -9
  36. data/spec/cli/ssh_cli_spec.rb +10 -10
  37. data/spec/cli/start_cli_spec.rb +15 -15
  38. data/spec/cli/verify_cli_spec.rb +4 -7
  39. data/spec/cli/version_cli_spec.rb +1 -2
  40. data/spec/cli/wait_cli_spec.rb +16 -16
  41. data/spec/config_spec.rb +7 -1
  42. data/spec/fixtures/show_droplets.json +7 -4
  43. data/spec/fixtures/show_droplets_paginated_first.json +10 -7
  44. data/spec/fixtures/show_droplets_paginated_last.json +11 -5
  45. data/spec/fixtures/show_droplets_private_ip.json +7 -4
  46. data/spec/middleware/base_spec.rb +1 -2
  47. data/spec/middleware/check_configuration_spec.rb +1 -1
  48. data/spec/middleware/check_credentials_spec.rb +1 -1
  49. data/spec/middleware/check_droplet_active_spec.rb +1 -1
  50. data/spec/middleware/check_droplet_inactive_spec.rb +1 -1
  51. data/spec/middleware/find_droplet_spec.rb +3 -5
  52. data/spec/middleware/find_image_spec.rb +3 -5
  53. data/spec/middleware/ssh_droplet_spec.rb +5 -10
  54. data/spec/shared/environment.rb +2 -18
  55. data/tugboat.gemspec +1 -2
  56. metadata +8 -6
@@ -79,7 +79,8 @@
79
79
  "metadata"
80
80
  ],
81
81
  "available": null
82
- }
82
+ },
83
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
83
84
  },
84
85
  {
85
86
  "id": 3164956,
@@ -160,7 +161,8 @@
160
161
  "metadata"
161
162
  ],
162
163
  "available": null
163
- }
164
+ },
165
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
164
166
  },
165
167
  {
166
168
  "id": 3164444,
@@ -241,7 +243,8 @@
241
243
  "metadata"
242
244
  ],
243
245
  "available": null
244
- }
246
+ },
247
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
245
248
  }
246
249
  ],
247
250
  "links": {
@@ -249,4 +252,4 @@
249
252
  "meta": {
250
253
  "total": 4
251
254
  }
252
- }
255
+ }
@@ -79,7 +79,8 @@
79
79
  "metadata"
80
80
  ],
81
81
  "available": null
82
- }
82
+ },
83
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
83
84
  },
84
85
  {
85
86
  "id": 3164956,
@@ -160,9 +161,10 @@
160
161
  "metadata"
161
162
  ],
162
163
  "available": null
163
- }
164
+ },
165
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
164
166
  },
165
- {
167
+ {
166
168
  "id": 3164444,
167
169
  "name": "page1example3.com",
168
170
  "memory": 512,
@@ -241,16 +243,17 @@
241
243
  "metadata"
242
244
  ],
243
245
  "available": null
244
- }
246
+ },
247
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
245
248
  }
246
249
  ],
247
250
  "links": {
248
251
  "pages": {
249
- "last": "https://api.digitalocean.com/v2/droplets?page=2&per_page=1",
250
- "next": "https://api.digitalocean.com/v2/droplets?page=2&per_page=1"
252
+ "last": "https://api.digitalocean.com/v2/droplets?page=1&per_page=3",
253
+ "next": "https://api.digitalocean.com/v2/droplets?page=2&per_page=3"
251
254
  }
252
255
  },
253
256
  "meta": {
254
257
  "total": 4
255
258
  }
256
- }
259
+ }
@@ -79,7 +79,8 @@
79
79
  "metadata"
80
80
  ],
81
81
  "available": null
82
- }
82
+ },
83
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
83
84
  },
84
85
  {
85
86
  "id": 3164956,
@@ -160,7 +161,8 @@
160
161
  "metadata"
161
162
  ],
162
163
  "available": null
163
- }
164
+ },
165
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
164
166
  },
165
167
  {
166
168
  "id": 3164444,
@@ -241,13 +243,17 @@
241
243
  "metadata"
242
244
  ],
243
245
  "available": null
244
- }
246
+ },
247
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
245
248
  }
246
249
  ],
247
250
  "links": {
248
-
251
+ "pages": {
252
+ "last": "https://api.digitalocean.com/v2/droplets?page=2&per_page=3",
253
+ "next": "https://api.digitalocean.com/v2/droplets?page=2&per_page=3"
254
+ }
249
255
  },
250
256
  "meta": {
251
257
  "total": 4
252
258
  }
253
- }
259
+ }
@@ -85,7 +85,8 @@
85
85
  "metadata"
86
86
  ],
87
87
  "available": null
88
- }
88
+ },
89
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
89
90
  },
90
91
  {
91
92
  "id": 3164956,
@@ -166,7 +167,8 @@
166
167
  "metadata"
167
168
  ],
168
169
  "available": null
169
- }
170
+ },
171
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
170
172
  },
171
173
  {
172
174
  "id": 3164444,
@@ -247,7 +249,8 @@
247
249
  "metadata"
248
250
  ],
249
251
  "available": null
250
- }
252
+ },
253
+ "size": {"slug":"512mb","memory":512,"vcpus":1,"disk":20,"transfer":1.0,"price_monthly":5.0,"price_hourly":0.00744,"regions":["ams2","ams3","blr1","fra1","lon1","nyc1","nyc2","nyc3","sfo1","sfo2","sgp1","tor1"],"available":true}
251
254
  }
252
255
  ],
253
256
  "links": {
@@ -255,4 +258,4 @@
255
258
  "meta": {
256
259
  "total": 4
257
260
  }
258
- }
261
+ }
@@ -7,8 +7,7 @@ describe Tugboat::Middleware::Base do
7
7
 
8
8
  describe '.initialize' do
9
9
  it 'prints a clear line' do
10
- expect($stdout).to receive(:print).with('')
11
- klass.new({})
10
+ expect { klass.new({}) }.to output('').to_stdout
12
11
  end
13
12
  end
14
13
  end
@@ -8,7 +8,7 @@ describe Tugboat::Middleware::CheckConfiguration do
8
8
  # Delete the temp configuration file.
9
9
  File.delete(project_path + '/tmp/tugboat')
10
10
 
11
- expect { described_class.new(app).call(env) }.to raise_error(SystemExit)
11
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{You must run `tugboat authorize` in order to connect to DigitalOcean}).to_stdout
12
12
  end
13
13
  end
14
14
  end
@@ -12,7 +12,7 @@ describe Tugboat::Middleware::CheckCredentials do
12
12
  # Inject the client.
13
13
  env['barge'] = ocean
14
14
 
15
- expect { described_class.new(app).call(env) }.to raise_error(SystemExit)
15
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{Failed to connect to DigitalOcean. Reason given from API: unauthorized - Unable to authenticate you.}).to_stdout
16
16
  expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).
17
17
  to have_been_made
18
18
  end
@@ -7,7 +7,7 @@ describe Tugboat::Middleware::CheckDropletActive do
7
7
  it 'raises an error when droplet is not active' do
8
8
  env['droplet_status'] = 'off'
9
9
 
10
- expect { described_class.new(app).call(env) }.to raise_error(SystemExit)
10
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{Droplet must be on for this operation to be successful.}).to_stdout
11
11
  end
12
12
  end
13
13
  end
@@ -7,7 +7,7 @@ describe Tugboat::Middleware::CheckDropletInactive do
7
7
  it 'raises an error when droplet is active' do
8
8
  env['droplet_status'] = 'active'
9
9
 
10
- expect { described_class.new(app).call(env) }.to raise_error(SystemExit)
10
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{Droplet must be off for this operation to be successful.}).to_stdout
11
11
  end
12
12
  end
13
13
  end
@@ -5,11 +5,9 @@ describe Tugboat::Middleware::FindDroplet do
5
5
 
6
6
  describe '.call' do
7
7
  it 'raises SystemExit with no droplet data' do
8
- expect { described_class.new(app).call(env) }.to raise_error(SystemExit)
9
-
10
- expect($stdout.string).to include 'Tugboat attempted to find a droplet with no arguments'
11
- expect($stdout.string).to include 'For more help run: '
12
- expect($stdout.string).to include 'Try running `tugboat '
8
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{Tugboat attempted to find a droplet with no argument}).to_stdout
9
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{For more help run:}).to_stdout
10
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{Try running `tugboat}).to_stdout
13
11
  end
14
12
  end
15
13
  end
@@ -5,11 +5,9 @@ describe Tugboat::Middleware::FindImage do
5
5
 
6
6
  describe '.call' do
7
7
  it 'raises SystemExit with no image data' do
8
- expect { described_class.new(app).call(env) }.to raise_error(SystemExit)
9
-
10
- expect($stdout.string).to include 'Tugboat attempted to find an image with no arguments'
11
- expect($stdout.string).to include 'For more help run: '
12
- expect($stdout.string).to include 'Try running `tugboat '
8
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{Tugboat attempted to find an image with no argument}).to_stdout
9
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{For more help run:}).to_stdout
10
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{Try running `tugboat}).to_stdout
13
11
  end
14
12
  end
15
13
  end
@@ -21,7 +21,7 @@ describe Tugboat::Middleware::SSHDroplet do
21
21
  env['droplet_ip'] = droplet_ip
22
22
  env['config'] = config
23
23
 
24
- described_class.new(app).call(env)
24
+ expect { described_class.new(app).call(env) }.to output(/SShing with options: -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=\/dev\/null -o IdentitiesOnly=yes -i #{File.expand_path(ssh_key_path)} -p 33 baz@33.33.33.10/).to_stdout
25
25
  end
26
26
 
27
27
  it 'exec ssh with IdentitiesOnly=no if no ssh_key_path in config' do
@@ -39,7 +39,7 @@ describe Tugboat::Middleware::SSHDroplet do
39
39
 
40
40
  env['config'] = config
41
41
 
42
- described_class.new(app).call(env)
42
+ expect { described_class.new(app).call(env) }.to output(/SShing with options: -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=\/dev\/null -o IdentitiesOnly=no -p 33 baz@33.33.33.10/).to_stdout
43
43
  end
44
44
 
45
45
  it 'executes ssh with custom options' do
@@ -63,7 +63,7 @@ describe Tugboat::Middleware::SSHDroplet do
63
63
  env['user_droplet_use_public_ip'] = true
64
64
  env['user_droplet_ssh_opts'] = '-e -q -X'
65
65
 
66
- described_class.new(app).call(env)
66
+ expect { described_class.new(app).call(env) }.to output(/SShing with options: -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=\/dev\/null -o IdentitiesOnly=yes -i #{File.expand_path(ssh_key_path)} -p 33 -e -q -X baz@33.33.33.10 echo hello/).to_stdout
67
67
  end
68
68
 
69
69
  it 'executes ssh with private IP if option chosen' do
@@ -87,7 +87,7 @@ describe Tugboat::Middleware::SSHDroplet do
87
87
  env['user_droplet_use_private_ip'] = true
88
88
  env['user_droplet_ssh_opts'] = '-e -q -X'
89
89
 
90
- described_class.new(app).call(env)
90
+ expect { described_class.new(app).call(env) }.to output(%r{You did! Using private IP for ssh...}).to_stdout
91
91
  end
92
92
 
93
93
  it 'errors if private IP option given but no Private IP on Droplet' do
@@ -97,12 +97,7 @@ describe Tugboat::Middleware::SSHDroplet do
97
97
  env['user_droplet_use_private_ip'] = true
98
98
  env['user_droplet_ssh_opts'] = '-e -q -X'
99
99
 
100
- expect { described_class.new(app).call(env) }.to raise_error(SystemExit)
101
-
102
- expect($stdout.string).to eq <<-eos
103
- Executing SSH on Droplet ...
104
- You asked to ssh to the private IP, but no Private IP found!
105
- eos
100
+ expect { described_class.new(app).call(env) }.to raise_error(SystemExit).and output(%r{You asked to ssh to the private IP, but no Private IP found}).to_stdout
106
101
  end
107
102
  end
108
103
  end
@@ -20,32 +20,16 @@ shared_context 'spec' do
20
20
  let(:private_networking) { 'false' }
21
21
  let(:backups_enabled) { 'false' }
22
22
  let(:ip6) { 'false' }
23
+ let(:timeout) { '15' }
23
24
  let(:ocean) { Barge::Client.new(access_token: access_token) }
24
25
  let(:app) { ->(env) {} }
25
26
  let(:env) { {} }
26
27
  let(:cli) { Tugboat::CLI.new }
27
28
 
28
29
  before do
29
- $stdout.sync = true
30
- $stderr.sync = true
31
-
32
30
  # Set a temprary project path and create fake config.
33
- config.create_config_file(access_token, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key_id, private_networking, backups_enabled, ip6)
31
+ config.create_config_file(access_token, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key_id, private_networking, backups_enabled, ip6, timeout)
34
32
  config.reload!
35
-
36
- # Keep track of the old stderr / out
37
- @orig_stderr = $stderr
38
- @orig_stdout = $stdout
39
-
40
- # Make them strings so we can manipulate and compare.
41
- $stderr = StringIO.new
42
- $stdout = StringIO.new
43
- end
44
-
45
- after do
46
- # Reassign the stderr / out so rspec can have it back.
47
- $stderr = @orig_stderr
48
- $stdout = @orig_stdout
49
33
  end
50
34
 
51
35
  after do
data/tugboat.gemspec CHANGED
@@ -22,8 +22,7 @@ Gem::Specification.new do |gem|
22
22
  gem.add_dependency 'barge', '0.12.0'
23
23
  gem.add_dependency 'droplet_kit', '2.2.0'
24
24
  gem.add_dependency 'ibsciss-middleware', '0.4.2'
25
- # Update back to faraday_middleware when https://github.com/lostisland/faraday_middleware/pull/157 merged
26
- gem.add_dependency 'faraday_middleware_safeyaml', '0.12.pre.safeyaml'
25
+ gem.add_dependency 'faraday_middleware', '0.12.2'
27
26
  gem.add_dependency 'faraday', '0.9.2'
28
27
  gem.add_dependency 'hashie', '3.5.5'
29
28
  gem.add_dependency 'activesupport', '4.2.9'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tugboat
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Pearkes
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-07-13 00:00:00.000000000 Z
13
+ date: 2017-12-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: thor
@@ -69,19 +69,19 @@ dependencies:
69
69
  - !ruby/object:Gem::Version
70
70
  version: 0.4.2
71
71
  - !ruby/object:Gem::Dependency
72
- name: faraday_middleware_safeyaml
72
+ name: faraday_middleware
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - '='
76
76
  - !ruby/object:Gem::Version
77
- version: 0.12.pre.safeyaml
77
+ version: 0.12.2
78
78
  type: :runtime
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
82
  - - '='
83
83
  - !ruby/object:Gem::Version
84
- version: 0.12.pre.safeyaml
84
+ version: 0.12.2
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: faraday
87
87
  requirement: !ruby/object:Gem::Requirement
@@ -375,6 +375,7 @@ files:
375
375
  - ".travis.yml"
376
376
  - CHANGELOG.md
377
377
  - CHANGELOG_old.md
378
+ - CODE_OF_CONDUCT.md
378
379
  - CONTRIBUTING.md
379
380
  - Gemfile
380
381
  - LICENSE.md
@@ -400,6 +401,7 @@ files:
400
401
  - lib/tugboat/middleware/check_credentials.rb
401
402
  - lib/tugboat/middleware/check_droplet_active.rb
402
403
  - lib/tugboat/middleware/check_droplet_inactive.rb
404
+ - lib/tugboat/middleware/check_snapshot_parameters.rb
403
405
  - lib/tugboat/middleware/config.rb
404
406
  - lib/tugboat/middleware/confirm_action.rb
405
407
  - lib/tugboat/middleware/create_droplet.rb
@@ -522,7 +524,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
522
524
  version: '0'
523
525
  requirements: []
524
526
  rubyforge_project:
525
- rubygems_version: 2.6.11
527
+ rubygems_version: 2.5.1
526
528
  signing_key:
527
529
  specification_version: 4
528
530
  summary: A command line tool for interacting with your DigitalOcean droplets.